mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-05-06 16:49:33 +00:00
Added clang-format spec - issue #35
This commit is contained in:
parent
e3f63e11cb
commit
cb2fd5736f
19
.clang-format
Normal file
19
.clang-format
Normal file
@ -0,0 +1,19 @@
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBraces: Attach
|
||||
ColumnLimit: 80
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
Language: Cpp
|
||||
PointerAlignment: Right
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
@ -22,9 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "parse.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "parse.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace peparse;
|
||||
@ -81,8 +81,12 @@ int printRelocs(void *N, VA relocAddr, reloc_type type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printSymbols(void *N, std::string &strName, uint32_t &value,
|
||||
int16_t §ionNumber, uint16_t &type, uint8_t &storageClass,
|
||||
int printSymbols(void *N,
|
||||
std::string &strName,
|
||||
uint32_t &value,
|
||||
int16_t §ionNumber,
|
||||
uint16_t &type,
|
||||
uint8_t &storageClass,
|
||||
uint8_t &numberOfAuxSymbols) {
|
||||
cout << "Symbol Name: " << strName << endl;
|
||||
cout << "Symbol Value: 0x" << to_string<uint32_t>(value, hex) << endl;
|
||||
@ -192,14 +196,13 @@ int printSymbols(void *N, std::string &strName, uint32_t &value,
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "Symbol Number of Aux Symbols: " << (uint32_t) numberOfAuxSymbols << endl;
|
||||
cout << "Symbol Number of Aux Symbols: " << (uint32_t) numberOfAuxSymbols
|
||||
<< endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printRsrc(void *N,
|
||||
resource r)
|
||||
{
|
||||
int printRsrc(void *N, resource r) {
|
||||
if (r.type_str.length())
|
||||
cout << "Type (string): " << r.type_str << endl;
|
||||
else
|
||||
@ -222,8 +225,7 @@ int printSecs(void *N,
|
||||
VA secBase,
|
||||
string &secName,
|
||||
image_section_header s,
|
||||
bounded_buffer *data)
|
||||
{
|
||||
bounded_buffer *data) {
|
||||
cout << "Sec Name: " << secName << endl;
|
||||
cout << "Sec Base: 0x" << to_string<uint64_t>(secBase, hex) << endl;
|
||||
if (data)
|
||||
@ -342,9 +344,9 @@ int main(int argc, char *argv[]) {
|
||||
cout << "Resources: " << endl;
|
||||
IterRsrc(p, printRsrc, NULL);
|
||||
DestructParsedPE(p);
|
||||
}
|
||||
else {
|
||||
cout << "Error: " << GetPEErr() << " (" << GetPEErrString() << ")" << endl;
|
||||
} else {
|
||||
cout << "Error: " << GetPEErr() << " (" << GetPEErrString() << ")"
|
||||
<< endl;
|
||||
cout << "Location: " << GetPEErrLoc() << endl;
|
||||
}
|
||||
}
|
||||
|
@ -22,17 +22,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "parse.h"
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include "parse.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -278,12 +278,8 @@ struct resource_dir_entry_sz {
|
||||
};
|
||||
|
||||
struct resource_dir_entry {
|
||||
inline resource_dir_entry(void)
|
||||
: ID(0),
|
||||
RVA(0),
|
||||
type(0),
|
||||
name(0),
|
||||
lang(0) {}
|
||||
inline resource_dir_entry(void) : ID(0), RVA(0), type(0), name(0), lang(0) {
|
||||
}
|
||||
|
||||
std::uint32_t ID;
|
||||
std::uint32_t RVA;
|
||||
|
@ -22,13 +22,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include "parse.h"
|
||||
#include "nt-headers.h"
|
||||
#include "to_string.h"
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -125,8 +125,7 @@ struct parsed_pe_internal {
|
||||
::uint32_t err = 0;
|
||||
std::string err_loc;
|
||||
|
||||
static const char *pe_err_str[] = {
|
||||
"None",
|
||||
static const char *pe_err_str[] = {"None",
|
||||
"Out of memory",
|
||||
"Invalid header",
|
||||
"Invalid section",
|
||||
@ -135,8 +134,7 @@ static const char *pe_err_str[] = {
|
||||
"Unable to read data",
|
||||
"Unable to open",
|
||||
"Unable to stat",
|
||||
"Bad magic"
|
||||
};
|
||||
"Bad magic"};
|
||||
|
||||
int GetPEErr() {
|
||||
return err;
|
||||
@ -150,9 +148,8 @@ string GetPEErrLoc() {
|
||||
return err_loc;
|
||||
}
|
||||
|
||||
static bool readCString(const bounded_buffer &buffer, ::uint32_t off,
|
||||
string &result)
|
||||
{
|
||||
static bool
|
||||
readCString(const bounded_buffer &buffer, ::uint32_t off, string &result) {
|
||||
if (off < buffer.bufLen) {
|
||||
::uint8_t *p = buffer.buf;
|
||||
::uint32_t n = buffer.bufLen;
|
||||
@ -210,7 +207,12 @@ bool parse_resource_id(bounded_buffer *data, ::uint32_t id, string &result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_resource_table(bounded_buffer *sectionData, ::uint32_t o, ::uint32_t virtaddr, ::uint32_t depth, resource_dir_entry *dirent, list<resource> &rsrcs) {
|
||||
bool parse_resource_table(bounded_buffer *sectionData,
|
||||
::uint32_t o,
|
||||
::uint32_t virtaddr,
|
||||
::uint32_t depth,
|
||||
resource_dir_entry *dirent,
|
||||
list<resource> &rsrcs) {
|
||||
::uint32_t i = 0;
|
||||
resource_dir_table rdt;
|
||||
|
||||
@ -245,21 +247,24 @@ bool parse_resource_table(bounded_buffer *sectionData, ::uint32_t o, ::uint32_t
|
||||
if (depth == 0) {
|
||||
rde->type = rde->ID;
|
||||
if (i < rdt.NameEntries) {
|
||||
if (!parse_resource_id(sectionData, rde->ID & 0x0FFFFFFF, rde->type_str)) {
|
||||
if (!parse_resource_id(
|
||||
sectionData, rde->ID & 0x0FFFFFFF, rde->type_str)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (depth == 1) {
|
||||
rde->name = rde->ID;
|
||||
if (i < rdt.NameEntries) {
|
||||
if (!parse_resource_id(sectionData, rde->ID & 0x0FFFFFFF, rde->name_str)) {
|
||||
if (!parse_resource_id(
|
||||
sectionData, rde->ID & 0x0FFFFFFF, rde->name_str)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (depth == 2) {
|
||||
rde->lang = rde->ID;
|
||||
if (i < rdt.NameEntries) {
|
||||
if (!parse_resource_id(sectionData, rde->ID & 0x0FFFFFFF, rde->lang_str)) {
|
||||
if (!parse_resource_id(
|
||||
sectionData, rde->ID & 0x0FFFFFFF, rde->lang_str)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -268,7 +273,12 @@ bool parse_resource_table(bounded_buffer *sectionData, ::uint32_t o, ::uint32_t
|
||||
// High bit 0 = RVA to RDT.
|
||||
// High bit 1 = RVA to RDE.
|
||||
if (rde->RVA & 0x80000000) {
|
||||
if (!parse_resource_table(sectionData, rde->RVA & 0x0FFFFFFF, virtaddr, depth + 1, rde, rsrcs)) {
|
||||
if (!parse_resource_table(sectionData,
|
||||
rde->RVA & 0x0FFFFFFF,
|
||||
virtaddr,
|
||||
depth + 1,
|
||||
rde,
|
||||
rsrcs)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -336,7 +346,10 @@ bool parse_resource_table(bounded_buffer *sectionData, ::uint32_t o, ::uint32_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getResources(bounded_buffer *b, bounded_buffer *fileBegin, list<section> secs, list<resource> &rsrcs) {
|
||||
bool getResources(bounded_buffer *b,
|
||||
bounded_buffer *fileBegin,
|
||||
list<section> secs,
|
||||
list<resource> &rsrcs) {
|
||||
|
||||
if (b == nullptr)
|
||||
return false;
|
||||
@ -346,7 +359,8 @@ bool getResources(bounded_buffer *b, bounded_buffer *fileBegin, list<section> se
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parse_resource_table(s.sectionData, 0, s.sec.VirtualAddress, 0, nullptr, rsrcs)) {
|
||||
if (!parse_resource_table(
|
||||
s.sectionData, 0, s.sec.VirtualAddress, 0, nullptr, rsrcs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -398,9 +412,11 @@ bool getSections( bounded_buffer *b,
|
||||
}
|
||||
|
||||
if (nthdr.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
thisSec.sectionBase = nthdr.OptionalHeader.ImageBase + curSec.VirtualAddress;
|
||||
thisSec.sectionBase =
|
||||
nthdr.OptionalHeader.ImageBase + curSec.VirtualAddress;
|
||||
} else if (nthdr.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
thisSec.sectionBase = nthdr.OptionalHeader64.ImageBase + curSec.VirtualAddress;
|
||||
thisSec.sectionBase =
|
||||
nthdr.OptionalHeader64.ImageBase + curSec.VirtualAddress;
|
||||
} else {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
}
|
||||
@ -658,10 +674,12 @@ bool getHeader(bounded_buffer *file, pe_header &p, bounded_buffer *&rem) {
|
||||
::uint32_t rem_size;
|
||||
if (p.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
// signature + file_header + optional_header_32
|
||||
rem_size = sizeof(::uint32_t) + sizeof(file_header) + sizeof(optional_header_32);
|
||||
rem_size =
|
||||
sizeof(::uint32_t) + sizeof(file_header) + sizeof(optional_header_32);
|
||||
} else if (p.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
// signature + file_header + optional_header_64
|
||||
rem_size = sizeof(::uint32_t) + sizeof(file_header) + sizeof(optional_header_64);
|
||||
rem_size =
|
||||
sizeof(::uint32_t) + sizeof(file_header) + sizeof(optional_header_64);
|
||||
} else {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
deleteBuffer(ntBuf);
|
||||
@ -691,7 +709,8 @@ bool getExports(parsed_pe *p) {
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
addr = exportDir.VirtualAddress + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
addr = exportDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
addr =
|
||||
exportDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -805,9 +824,11 @@ bool getExports(parsed_pe *p) {
|
||||
|
||||
VA ordinalTableVA;
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
ordinalTableVA = ordinalTableRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
ordinalTableVA =
|
||||
ordinalTableRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
ordinalTableVA = ordinalTableRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
ordinalTableVA =
|
||||
ordinalTableRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -917,9 +938,11 @@ bool getRelocations(parsed_pe *p) {
|
||||
section d;
|
||||
VA vaAddr;
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
vaAddr = relocDir.VirtualAddress + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
vaAddr =
|
||||
relocDir.VirtualAddress + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
vaAddr = relocDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
vaAddr =
|
||||
relocDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -975,7 +998,8 @@ bool getRelocations(parsed_pe *p) {
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
relocVA = pageRva + offset + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
relocVA = pageRva + offset + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
relocVA =
|
||||
pageRva + offset + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -1013,7 +1037,8 @@ bool getImports(parsed_pe *p) {
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
addr = importDir.VirtualAddress + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
addr = importDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
addr =
|
||||
importDir.VirtualAddress + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -1035,8 +1060,7 @@ bool getImports(parsed_pe *p) {
|
||||
READ_DWORD(c.sectionData, offt, curEnt, AddressRVA);
|
||||
|
||||
// are all the fields in curEnt null? then we break
|
||||
if (curEnt.LookupTableRVA == 0 &&
|
||||
curEnt.NameRVA == 0 &&
|
||||
if (curEnt.LookupTableRVA == 0 && curEnt.NameRVA == 0 &&
|
||||
curEnt.AddressRVA == 0) {
|
||||
break;
|
||||
}
|
||||
@ -1061,30 +1085,36 @@ bool getImports(parsed_pe *p) {
|
||||
if (!readCString(*nameSec.sectionData, nameOff, modName)) {
|
||||
return false;
|
||||
}
|
||||
std::transform(modName.begin(), modName.end(), modName.begin(), ::toupper);
|
||||
std::transform(
|
||||
modName.begin(), modName.end(), modName.begin(), ::toupper);
|
||||
|
||||
// then, try and get all of the sub-symbols
|
||||
VA lookupVA = 0;
|
||||
if (curEnt.LookupTableRVA != 0) {
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
lookupVA = curEnt.LookupTableRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
lookupVA =
|
||||
curEnt.LookupTableRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
lookupVA = curEnt.LookupTableRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
lookupVA =
|
||||
curEnt.LookupTableRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (curEnt.AddressRVA != 0) {
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
lookupVA = curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
lookupVA =
|
||||
curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
lookupVA = curEnt.AddressRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
lookupVA =
|
||||
curEnt.AddressRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
section lookupSec;
|
||||
if (lookupVA == 0 || !getSecForVA(p->internal->secs, lookupVA, lookupSec)) {
|
||||
if (lookupVA == 0 ||
|
||||
!getSecForVA(p->internal->secs, lookupVA, lookupSec)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1150,9 +1180,11 @@ bool getImports(parsed_pe *p) {
|
||||
importent ent;
|
||||
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
ent.addr = offInTable + curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
ent.addr = offInTable + curEnt.AddressRVA +
|
||||
p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
ent.addr = offInTable + curEnt.AddressRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
ent.addr = offInTable + curEnt.AddressRVA +
|
||||
p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -1167,9 +1199,11 @@ bool getImports(parsed_pe *p) {
|
||||
importent ent;
|
||||
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
ent.addr = offInTable + curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
ent.addr = offInTable + curEnt.AddressRVA +
|
||||
p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
ent.addr = offInTable + curEnt.AddressRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
ent.addr = offInTable + curEnt.AddressRVA +
|
||||
p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -1203,8 +1237,9 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t strTableOffset = p->peHeader.nt.FileHeader.PointerToSymbolTable
|
||||
+ (p->peHeader.nt.FileHeader.NumberOfSymbols * SYMTAB_RECORD_LEN);
|
||||
uint32_t strTableOffset =
|
||||
p->peHeader.nt.FileHeader.PointerToSymbolTable +
|
||||
(p->peHeader.nt.FileHeader.NumberOfSymbols * SYMTAB_RECORD_LEN);
|
||||
|
||||
uint32_t offset = p->peHeader.nt.FileHeader.PointerToSymbolTable;
|
||||
|
||||
@ -1296,8 +1331,7 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
// Read auxiliary symbol records
|
||||
|
||||
if (sym.storageClass == IMAGE_SYM_CLASS_EXTERNAL &&
|
||||
SYMBOL_TYPE_HI(sym) == 0x20 &&
|
||||
sym.sectionNumber > 0) {
|
||||
SYMBOL_TYPE_HI(sym) == 0x20 && sym.sectionNumber > 0) {
|
||||
// Auxiliary Format 1: Function Definitions
|
||||
|
||||
for (uint8_t n = 0; n < sym.numberOfAuxSymbols; n++) {
|
||||
@ -1369,8 +1403,7 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
sym.aux_symbols_f2.push_back(asym);
|
||||
}
|
||||
} else if (sym.storageClass == IMAGE_SYM_CLASS_EXTERNAL &&
|
||||
sym.sectionNumber == IMAGE_SYM_UNDEFINED &&
|
||||
sym.value == 0) {
|
||||
sym.sectionNumber == IMAGE_SYM_UNDEFINED && sym.value == 0) {
|
||||
// Auxiliary Format 3: Weak Externals
|
||||
|
||||
for (uint8_t n = 0; n < sym.numberOfAuxSymbols; n++) {
|
||||
@ -1613,7 +1646,12 @@ void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd) {
|
||||
list<symbol> &l = pe->internal->symbols;
|
||||
|
||||
for (symbol s : l) {
|
||||
if (cb(cbd, s.strName, s.value, s.sectionNumber, s.type, s.storageClass,
|
||||
if (cb(cbd,
|
||||
s.strName,
|
||||
s.value,
|
||||
s.sectionNumber,
|
||||
s.type,
|
||||
s.storageClass,
|
||||
s.numberOfAuxSymbols) != 0) {
|
||||
break;
|
||||
}
|
||||
@ -1668,9 +1706,11 @@ bool GetEntryPoint(parsed_pe *pe, VA &v) {
|
||||
nt_header_32 *nthdr = &pe->peHeader.nt;
|
||||
|
||||
if (nthdr->OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
v = nthdr->OptionalHeader.AddressOfEntryPoint + nthdr->OptionalHeader.ImageBase;
|
||||
v = nthdr->OptionalHeader.AddressOfEntryPoint +
|
||||
nthdr->OptionalHeader.ImageBase;
|
||||
} else if (nthdr->OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
v = nthdr->OptionalHeader64.AddressOfEntryPoint + nthdr->OptionalHeader64.ImageBase;
|
||||
v = nthdr->OptionalHeader64.AddressOfEntryPoint +
|
||||
nthdr->OptionalHeader64.ImageBase;
|
||||
} else {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
return false;
|
||||
|
@ -24,8 +24,8 @@ THE SOFTWARE.
|
||||
|
||||
#ifndef _PARSE_H
|
||||
#define _PARSE_H
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "nt-headers.h"
|
||||
#include "to_string.h"
|
||||
@ -34,7 +34,6 @@ THE SOFTWARE.
|
||||
#define __typeof__(x) std::remove_reference < decltype(x) > ::type
|
||||
#endif
|
||||
|
||||
|
||||
#define PE_ERR(x) \
|
||||
err = (pe_err) x; \
|
||||
err_loc.assign(__func__); \
|
||||
@ -148,15 +147,14 @@ bool readDword(bounded_buffer *b, std::uint32_t offset, std::uint32_t &out);
|
||||
bool readQword(bounded_buffer *b, std::uint32_t offset, std::uint64_t &out);
|
||||
|
||||
bounded_buffer *readFileToFileBuffer(const char *filePath);
|
||||
bounded_buffer *splitBuffer(bounded_buffer *b, std::uint32_t from, std::uint32_t to);
|
||||
bounded_buffer *
|
||||
splitBuffer(bounded_buffer *b, std::uint32_t from, std::uint32_t to);
|
||||
void deleteBuffer(bounded_buffer *b);
|
||||
uint64_t bufLen(bounded_buffer *b);
|
||||
|
||||
struct parsed_pe_internal;
|
||||
|
||||
typedef struct _pe_header {
|
||||
nt_header_32 nt;
|
||||
} pe_header;
|
||||
typedef struct _pe_header { nt_header_32 nt; } pe_header;
|
||||
|
||||
typedef struct _parsed_pe {
|
||||
bounded_buffer *fileBuffer;
|
||||
@ -192,7 +190,13 @@ typedef int (*iterReloc)(void *, VA, reloc_type);
|
||||
void IterRelocs(parsed_pe *pe, iterReloc cb, void *cbd);
|
||||
|
||||
// Iterate over symbols (symbol table) in the PE file
|
||||
typedef int (*iterSymbol)(void *, std::string &, uint32_t &, int16_t &, uint16_t &, uint8_t &, uint8_t &);
|
||||
typedef int (*iterSymbol)(void *,
|
||||
std::string &,
|
||||
uint32_t &,
|
||||
int16_t &,
|
||||
uint16_t &,
|
||||
uint8_t &,
|
||||
uint8_t &);
|
||||
void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd);
|
||||
|
||||
// iterate over the exports
|
||||
@ -200,7 +204,8 @@ typedef int (*iterExp)(void *, VA, std::string &, std::string &);
|
||||
void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd);
|
||||
|
||||
// iterate over sections
|
||||
typedef int (*iterSec)(void *, VA secBase, std::string &, image_section_header, bounded_buffer *b);
|
||||
typedef int (*iterSec)(
|
||||
void *, VA secBase, std::string &, image_section_header, bounded_buffer *b);
|
||||
void IterSec(parsed_pe *pe, iterSec cb, void *cbd);
|
||||
|
||||
// get byte at VA in PE
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
namespace peparse {
|
||||
template <class T>
|
||||
static
|
||||
std::string to_string(T t, std::ios_base & (*f)(std::ios_base&)) {
|
||||
static std::string to_string(T t, std::ios_base &(*f)(std::ios_base &) ) {
|
||||
std::ostringstream oss;
|
||||
oss << f << t;
|
||||
return oss.str();
|
||||
|
269
python/pepy.cpp
269
python/pepy.cpp
@ -25,9 +25,9 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "parse.h"
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
#include "parse.h"
|
||||
|
||||
using namespace peparse;
|
||||
|
||||
@ -41,30 +41,26 @@ static PyObject *pepy_##OBJ##_get_##ATTR(PyObject *self, void *closure) { \
|
||||
}
|
||||
|
||||
#define OBJECTGETTER(OBJ, ATTR, DOC) \
|
||||
{ (char *) #ATTR, (getter) pepy_##OBJ##_get_##ATTR, \
|
||||
(setter) pepy_attr_not_writable, \
|
||||
(char *) #DOC, NULL }
|
||||
{ \
|
||||
(char *) #ATTR, (getter) pepy_##OBJ##_get_##ATTR, \
|
||||
(setter) pepy_attr_not_writable, (char *) #DOC, NULL \
|
||||
}
|
||||
|
||||
/* 'OPTIONAL' references the fact that these are from the Optional Header */
|
||||
#define OBJECTGETTER_OPTIONAL(ATTR, DOC) \
|
||||
{ (char *) #ATTR, (getter) pepy_parsed_get_optional_##ATTR, \
|
||||
(setter) pepy_attr_not_writable, \
|
||||
(char *) #DOC, NULL }
|
||||
{ \
|
||||
(char *) #ATTR, (getter) pepy_parsed_get_optional_##ATTR, \
|
||||
(setter) pepy_attr_not_writable, (char *) #DOC, NULL \
|
||||
}
|
||||
|
||||
static PyObject *pepy_error;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
} pepy;
|
||||
typedef struct { PyObject_HEAD } pepy;
|
||||
|
||||
typedef struct { PyObject_HEAD parsed_pe *pe; } pepy_parsed;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
parsed_pe *pe;
|
||||
} pepy_parsed;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *name;
|
||||
PyObject_HEAD PyObject *name;
|
||||
PyObject *base;
|
||||
PyObject *length;
|
||||
PyObject *virtaddr;
|
||||
@ -76,8 +72,7 @@ typedef struct {
|
||||
} pepy_section;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *type_str;
|
||||
PyObject_HEAD PyObject *type_str;
|
||||
PyObject *name_str;
|
||||
PyObject *lang_str;
|
||||
PyObject *type;
|
||||
@ -90,32 +85,31 @@ typedef struct {
|
||||
} pepy_resource;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *name;
|
||||
PyObject_HEAD PyObject *name;
|
||||
PyObject *sym;
|
||||
PyObject *addr;
|
||||
} pepy_import;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *mod;
|
||||
PyObject_HEAD PyObject *mod;
|
||||
PyObject *func;
|
||||
PyObject *addr;
|
||||
} pepy_export;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *type;
|
||||
PyObject_HEAD PyObject *type;
|
||||
PyObject *addr;
|
||||
} pepy_relocation;
|
||||
|
||||
/* None of the attributes in these objects are writable. */
|
||||
static int pepy_attr_not_writable(PyObject *self, PyObject *value, void *closure) {
|
||||
static int
|
||||
pepy_attr_not_writable(PyObject *self, PyObject *value, void *closure) {
|
||||
PyErr_SetString(PyExc_TypeError, "Attribute not writable.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PyObject *pepy_import_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_import_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_import *self;
|
||||
|
||||
self = (pepy_import *) type->tp_alloc(type, 0);
|
||||
@ -124,7 +118,8 @@ static PyObject *pepy_import_new(PyTypeObject *type, PyObject *args, PyObject *k
|
||||
}
|
||||
|
||||
static int pepy_import_init(pepy_import *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args, "OOO:pepy_import_init", &self->name, &self->sym, &self->addr))
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "OOO:pepy_import_init", &self->name, &self->sym, &self->addr))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@ -144,12 +139,10 @@ static PyGetSetDef pepy_import_getseters[] = {
|
||||
OBJECTGETTER(import, name, "Name"),
|
||||
OBJECTGETTER(import, sym, "Symbol"),
|
||||
OBJECTGETTER(import, addr, "Address"),
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_import_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.import", /* tp_name */
|
||||
sizeof(pepy_import), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -189,7 +182,8 @@ static PyTypeObject pepy_import_type = {
|
||||
pepy_import_new /* tp_new */
|
||||
};
|
||||
|
||||
static PyObject *pepy_export_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_export_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_export *self;
|
||||
|
||||
self = (pepy_export *) type->tp_alloc(type, 0);
|
||||
@ -198,7 +192,8 @@ static PyObject *pepy_export_new(PyTypeObject *type, PyObject *args, PyObject *k
|
||||
}
|
||||
|
||||
static int pepy_export_init(pepy_export *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args, "OOO:pepy_export_init", &self->mod, &self->func, &self->addr))
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "OOO:pepy_export_init", &self->mod, &self->func, &self->addr))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@ -218,12 +213,10 @@ static PyGetSetDef pepy_export_getseters[] = {
|
||||
OBJECTGETTER(export, mod, "Module"),
|
||||
OBJECTGETTER(export, func, "Function"),
|
||||
OBJECTGETTER(export, addr, "Address"),
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_export_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.export", /* tp_name */
|
||||
sizeof(pepy_export), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -263,7 +256,8 @@ static PyTypeObject pepy_export_type = {
|
||||
pepy_export_new /* tp_new */
|
||||
};
|
||||
|
||||
static PyObject *pepy_relocation_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_relocation_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_relocation *self;
|
||||
|
||||
self = (pepy_relocation *) type->tp_alloc(type, 0);
|
||||
@ -271,8 +265,10 @@ static PyObject *pepy_relocation_new(PyTypeObject *type, PyObject *args, PyObjec
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int pepy_relocation_init(pepy_relocation *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args, "OO:pepy_relocation_init", &self->type, &self->addr))
|
||||
static int
|
||||
pepy_relocation_init(pepy_relocation *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "OO:pepy_relocation_init", &self->type, &self->addr))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@ -289,12 +285,10 @@ PEPY_OBJECT_GET(relocation, addr)
|
||||
static PyGetSetDef pepy_relocation_getseters[] = {
|
||||
OBJECTGETTER(relocation, type, "Type"),
|
||||
OBJECTGETTER(relocation, addr, "Address"),
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_relocation_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.relocation", /* tp_name */
|
||||
sizeof(pepy_relocation), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -334,7 +328,8 @@ static PyTypeObject pepy_relocation_type = {
|
||||
pepy_relocation_new /* tp_new */
|
||||
};
|
||||
|
||||
static PyObject *pepy_section_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_section_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_section *self;
|
||||
|
||||
self = (pepy_section *) type->tp_alloc(type, 0);
|
||||
@ -342,8 +337,19 @@ static PyObject *pepy_section_new(PyTypeObject *type, PyObject *args, PyObject *
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int pepy_section_init(pepy_section *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args, "OOOOOOOOO:pepy_section_init", &self->name, &self->base, &self->length, &self->virtaddr, &self->virtsize, &self->numrelocs, &self->numlinenums, &self->characteristics, &self->data))
|
||||
static int
|
||||
pepy_section_init(pepy_section *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"OOOOOOOOO:pepy_section_init",
|
||||
&self->name,
|
||||
&self->base,
|
||||
&self->length,
|
||||
&self->virtaddr,
|
||||
&self->virtsize,
|
||||
&self->numrelocs,
|
||||
&self->numlinenums,
|
||||
&self->characteristics,
|
||||
&self->data))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@ -381,12 +387,10 @@ static PyGetSetDef pepy_section_getseters[] = {
|
||||
OBJECTGETTER(section, numlinenums, "Number of line numbers"),
|
||||
OBJECTGETTER(section, characteristics, "Characteristics"),
|
||||
OBJECTGETTER(section, data, "Section data"),
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_section_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.section", /* tp_name */
|
||||
sizeof(pepy_section), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -426,7 +430,8 @@ static PyTypeObject pepy_section_type = {
|
||||
pepy_section_new /* tp_new */
|
||||
};
|
||||
|
||||
static PyObject *pepy_resource_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_resource_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_resource *self;
|
||||
|
||||
self = (pepy_resource *) type->tp_alloc(type, 0);
|
||||
@ -434,8 +439,20 @@ static PyObject *pepy_resource_new(PyTypeObject *type, PyObject *args, PyObject
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int pepy_resource_init(pepy_resource *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args, "OOOOOOOOOO:pepy_resource_init", &self->type_str, &self->name_str, &self->lang_str, &self->type, &self->name, &self->lang, &self->codepage, &self->RVA, &self->size, &self->data))
|
||||
static int
|
||||
pepy_resource_init(pepy_resource *self, PyObject *args, PyObject *kwds) {
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"OOOOOOOOOO:pepy_resource_init",
|
||||
&self->type_str,
|
||||
&self->name_str,
|
||||
&self->lang_str,
|
||||
&self->type,
|
||||
&self->name,
|
||||
&self->lang,
|
||||
&self->codepage,
|
||||
&self->RVA,
|
||||
&self->size,
|
||||
&self->data))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -557,10 +574,11 @@ static PyObject *pepy_resource_type_as_str(PyObject *self, PyObject *args) {
|
||||
}
|
||||
|
||||
static PyMethodDef pepy_resource_methods[] = {
|
||||
{ "type_as_str", pepy_resource_type_as_str, METH_NOARGS,
|
||||
{"type_as_str",
|
||||
pepy_resource_type_as_str,
|
||||
METH_NOARGS,
|
||||
"Return the resource type as a string."},
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyGetSetDef pepy_resource_getseters[] = {
|
||||
OBJECTGETTER(resource, type_str, "Type string"),
|
||||
@ -573,12 +591,10 @@ static PyGetSetDef pepy_resource_getseters[] = {
|
||||
OBJECTGETTER(resource, RVA, "RVA"),
|
||||
OBJECTGETTER(resource, size, "Size (specified in RDAT)"),
|
||||
OBJECTGETTER(resource, data, "Resource data"),
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_resource_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.resource", /* tp_name */
|
||||
sizeof(pepy_resource), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -618,7 +634,8 @@ static PyTypeObject pepy_resource_type = {
|
||||
pepy_resource_new /* tp_new */
|
||||
};
|
||||
|
||||
static PyObject *pepy_parsed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
static PyObject *
|
||||
pepy_parsed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
|
||||
pepy_parsed *self;
|
||||
|
||||
self = (pepy_parsed *) type->tp_alloc(type, 0);
|
||||
@ -731,8 +748,7 @@ static PyObject *pepy_data_converter(bounded_buffer *data) {
|
||||
if (!data || !data->buf) {
|
||||
str = "";
|
||||
len = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
str = (const char *) data->buf;
|
||||
len = data->bufLen;
|
||||
}
|
||||
@ -746,7 +762,11 @@ static PyObject *pepy_data_converter(bounded_buffer *data) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int section_callback(void *cbd, VA base, std::string &name, image_section_header s, bounded_buffer *data) {
|
||||
int section_callback(void *cbd,
|
||||
VA base,
|
||||
std::string &name,
|
||||
image_section_header s,
|
||||
bounded_buffer *data) {
|
||||
uint32_t buflen;
|
||||
PyObject *sect;
|
||||
PyObject *tuple;
|
||||
@ -771,10 +791,17 @@ int section_callback(void *cbd, VA base, std::string &name, image_section_header
|
||||
* The tuple item order is important here. It is passed into the
|
||||
* section type initialization and parsed there.
|
||||
*/
|
||||
tuple = Py_BuildValue("sKKIIHHIO&", name.c_str(), base, buflen,
|
||||
s.VirtualAddress, s.Misc.VirtualSize,
|
||||
s.NumberOfRelocations, s.NumberOfLinenumbers,
|
||||
s.Characteristics, pepy_data_converter, data);
|
||||
tuple = Py_BuildValue("sKKIIHHIO&",
|
||||
name.c_str(),
|
||||
base,
|
||||
buflen,
|
||||
s.VirtualAddress,
|
||||
s.Misc.VirtualSize,
|
||||
s.NumberOfRelocations,
|
||||
s.NumberOfLinenumbers,
|
||||
s.Characteristics,
|
||||
pepy_data_converter,
|
||||
data);
|
||||
if (!tuple)
|
||||
return 1;
|
||||
|
||||
@ -819,7 +846,21 @@ int resource_callback(void *cbd, resource r) {
|
||||
* The tuple item order is important here. It is passed into the
|
||||
* section type initialization and parsed there.
|
||||
*/
|
||||
tuple = Py_BuildValue("s#s#s#IIIIIIO&", r.type_str.c_str(), r.type_str.length(), r.name_str.c_str(), r.name_str.length(), r.lang_str.c_str(), r.lang_str.length(), r.type, r.name, r.lang, r.codepage, r.RVA, r.size, pepy_data_converter, r.buf);
|
||||
tuple = Py_BuildValue("s#s#s#IIIIIIO&",
|
||||
r.type_str.c_str(),
|
||||
r.type_str.length(),
|
||||
r.name_str.c_str(),
|
||||
r.name_str.length(),
|
||||
r.lang_str.c_str(),
|
||||
r.lang_str.length(),
|
||||
r.type,
|
||||
r.name,
|
||||
r.lang,
|
||||
r.codepage,
|
||||
r.RVA,
|
||||
r.size,
|
||||
pepy_data_converter,
|
||||
r.buf);
|
||||
if (!tuple)
|
||||
return 1;
|
||||
|
||||
@ -996,7 +1037,8 @@ static PyObject *pepy_parsed_get_relocations(PyObject *self, PyObject *args) {
|
||||
|
||||
#define PEPY_PARSED_GET(ATTR, VAL) \
|
||||
static PyObject *pepy_parsed_get_##ATTR(PyObject *self, void *closure) { \
|
||||
PyObject *ret = PyInt_FromLong(((pepy_parsed *) self)->pe->peHeader.nt.VAL); \
|
||||
PyObject *ret = \
|
||||
PyInt_FromLong(((pepy_parsed *) self)->pe->peHeader.nt.VAL); \
|
||||
if (!ret) \
|
||||
PyErr_SetString(PyExc_AttributeError, "Error getting attribute."); \
|
||||
return ret; \
|
||||
@ -1018,14 +1060,19 @@ PEPY_PARSED_GET(magic, OptionalMagic)
|
||||
* This is why "magic" is handled above, and not here.
|
||||
*/
|
||||
#define PEPY_PARSED_GET_OPTIONAL(ATTR, VAL) \
|
||||
static PyObject *pepy_parsed_get_optional_##ATTR(PyObject *self, void *closure) { \
|
||||
static PyObject *pepy_parsed_get_optional_##ATTR(PyObject *self, \
|
||||
void *closure) { \
|
||||
PyObject *ret = NULL; \
|
||||
if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) { \
|
||||
ret = PyInt_FromLong(((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader.VAL); \
|
||||
if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == \
|
||||
NT_OPTIONAL_32_MAGIC) { \
|
||||
ret = PyInt_FromLong( \
|
||||
((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader.VAL); \
|
||||
if (!ret) \
|
||||
PyErr_SetString(PyExc_AttributeError, "Error getting attribute."); \
|
||||
} else if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) { \
|
||||
ret = PyInt_FromLong(((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader64.VAL); \
|
||||
} else if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == \
|
||||
NT_OPTIONAL_64_MAGIC) { \
|
||||
ret = PyInt_FromLong( \
|
||||
((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader64.VAL); \
|
||||
if (!ret) \
|
||||
PyErr_SetString(PyExc_AttributeError, "Error getting attribute."); \
|
||||
} else { \
|
||||
@ -1063,13 +1110,17 @@ PEPY_PARSED_GET_OPTIONAL(rvasandsize, NumberOfRvaAndSizes);
|
||||
* BaseOfData is only in PE32, not PE32+. Thus, it uses a non-standard
|
||||
* getter function compared to the other shared fields.
|
||||
*/
|
||||
static PyObject *pepy_parsed_get_optional_baseofdata(PyObject *self, void *closure) {
|
||||
static PyObject *pepy_parsed_get_optional_baseofdata(PyObject *self,
|
||||
void *closure) {
|
||||
PyObject *ret = NULL;
|
||||
if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
ret = PyInt_FromLong(((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader.BaseOfData);
|
||||
if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic ==
|
||||
NT_OPTIONAL_32_MAGIC) {
|
||||
ret = PyInt_FromLong(
|
||||
((pepy_parsed *) self)->pe->peHeader.nt.OptionalHeader.BaseOfData);
|
||||
if (!ret)
|
||||
PyErr_SetString(PyExc_AttributeError, "Error getting attribute.");
|
||||
} else if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
} else if (((pepy_parsed *) self)->pe->peHeader.nt.OptionalMagic ==
|
||||
NT_OPTIONAL_64_MAGIC) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Not available on PE32+.");
|
||||
} else {
|
||||
PyErr_SetString(pepy_error, "Bad magic value.");
|
||||
@ -1110,33 +1161,46 @@ static PyGetSetDef pepy_parsed_getseters[] = {
|
||||
OBJECTGETTER_OPTIONAL(loaderflags, "Loader flags"),
|
||||
OBJECTGETTER_OPTIONAL(rvasandsize, "Number of RVA and sizes"),
|
||||
/* Base of data is only available in PE32, not PE32+. */
|
||||
{ (char *) "baseofdata", (getter) pepy_parsed_get_optional_baseofdata,
|
||||
{(char *) "baseofdata",
|
||||
(getter) pepy_parsed_get_optional_baseofdata,
|
||||
(setter) pepy_attr_not_writable,
|
||||
(char *) "Base address of data", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
(char *) "Base address of data",
|
||||
NULL},
|
||||
{NULL}};
|
||||
|
||||
static PyMethodDef pepy_parsed_methods[] = {
|
||||
{ "get_entry_point", pepy_parsed_get_entry_point, METH_NOARGS,
|
||||
{"get_entry_point",
|
||||
pepy_parsed_get_entry_point,
|
||||
METH_NOARGS,
|
||||
"Return the entry point address."},
|
||||
{ "get_bytes", pepy_parsed_get_bytes, METH_VARARGS,
|
||||
{"get_bytes",
|
||||
pepy_parsed_get_bytes,
|
||||
METH_VARARGS,
|
||||
"Return the first N bytes at a given address."},
|
||||
{ "get_sections", pepy_parsed_get_sections, METH_NOARGS,
|
||||
{"get_sections",
|
||||
pepy_parsed_get_sections,
|
||||
METH_NOARGS,
|
||||
"Return a list of section objects."},
|
||||
{ "get_imports", pepy_parsed_get_imports, METH_NOARGS,
|
||||
{"get_imports",
|
||||
pepy_parsed_get_imports,
|
||||
METH_NOARGS,
|
||||
"Return a list of import objects."},
|
||||
{ "get_exports", pepy_parsed_get_exports, METH_NOARGS,
|
||||
{"get_exports",
|
||||
pepy_parsed_get_exports,
|
||||
METH_NOARGS,
|
||||
"Return a list of export objects."},
|
||||
{ "get_relocations", pepy_parsed_get_relocations, METH_NOARGS,
|
||||
{"get_relocations",
|
||||
pepy_parsed_get_relocations,
|
||||
METH_NOARGS,
|
||||
"Return a list of relocation objects."},
|
||||
{ "get_resources", pepy_parsed_get_resources, METH_NOARGS,
|
||||
{"get_resources",
|
||||
pepy_parsed_get_resources,
|
||||
METH_NOARGS,
|
||||
"Return a list of resource objects."},
|
||||
{ NULL }
|
||||
};
|
||||
{NULL}};
|
||||
|
||||
static PyTypeObject pepy_parsed_type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
PyObject_HEAD_INIT(NULL) 0, /* ob_size */
|
||||
"pepy.parsed", /* tp_name */
|
||||
sizeof(pepy_parsed), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
@ -1195,10 +1259,13 @@ static PyObject *pepy_parse(PyObject *self, PyObject *args) {
|
||||
err_str = (char *) malloc(len);
|
||||
if (!err_str)
|
||||
return PyErr_NoMemory();
|
||||
snprintf(err_str, len, "%s (%s)", GetPEErrString().c_str(), GetPEErrLoc().c_str());
|
||||
snprintf(err_str,
|
||||
len,
|
||||
"%s (%s)",
|
||||
GetPEErrString().c_str(),
|
||||
GetPEErrLoc().c_str());
|
||||
PyErr_SetString(pepy_error, err_str);
|
||||
}
|
||||
else
|
||||
} else
|
||||
PyErr_SetString(pepy_error, "Unable to init new parsed object.");
|
||||
return NULL;
|
||||
}
|
||||
@ -1207,9 +1274,7 @@ static PyObject *pepy_parse(PyObject *self, PyObject *args) {
|
||||
}
|
||||
|
||||
static PyMethodDef pepy_methods[] = {
|
||||
{ "parse", pepy_parse, METH_VARARGS, "Parse PE from file." },
|
||||
{ NULL }
|
||||
};
|
||||
{"parse", pepy_parse, METH_VARARGS, "Parse PE from file."}, {NULL}};
|
||||
|
||||
PyMODINIT_FUNC initpepy(void) {
|
||||
PyObject *m;
|
||||
|
Loading…
x
Reference in New Issue
Block a user