mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-04-27 21:04:31 +00:00
Expose more export information, like forwarded export and ordinal (#161)
* Expose more export information namely, ordinal and forwarded export * ensure IterExpVA's behavior is not changed * Added description in the header file
This commit is contained in:
parent
af52e5ee8a
commit
f0097d2d9f
@ -24,6 +24,7 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -35,19 +36,34 @@ using namespace peparse;
|
|||||||
|
|
||||||
int printExps(void *N,
|
int printExps(void *N,
|
||||||
const VA &funcAddr,
|
const VA &funcAddr,
|
||||||
|
std::uint16_t ordinal,
|
||||||
const std::string &mod,
|
const std::string &mod,
|
||||||
const std::string &func) {
|
const std::string &func,
|
||||||
|
const std::string &fwd) {
|
||||||
static_cast<void>(N);
|
static_cast<void>(N);
|
||||||
|
|
||||||
auto address = static_cast<std::uint32_t>(funcAddr);
|
auto address = static_cast<std::uint32_t>(funcAddr);
|
||||||
|
|
||||||
std::cout << "EXP: ";
|
// save default formatting
|
||||||
|
std::ios initial(nullptr);
|
||||||
|
initial.copyfmt(std::cout);
|
||||||
|
|
||||||
|
std::cout << "EXP #";
|
||||||
|
std::cout << ordinal;
|
||||||
|
std::cout << ": ";
|
||||||
std::cout << mod;
|
std::cout << mod;
|
||||||
std::cout << "!";
|
std::cout << "!";
|
||||||
std::cout << func;
|
std::cout << func;
|
||||||
std::cout << ": 0x";
|
std::cout << ": ";
|
||||||
std::cout << std::hex << address;
|
if (!fwd.empty()) {
|
||||||
|
std::cout << fwd;
|
||||||
|
} else {
|
||||||
|
std::cout << std::showbase << std::hex << address;
|
||||||
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
|
|
||||||
|
// restore default formatting
|
||||||
|
std::cout.copyfmt(initial);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +456,7 @@ int main(int argc, char *argv[]) {
|
|||||||
IterSec(p, printSecs, NULL);
|
IterSec(p, printSecs, NULL);
|
||||||
std::cout << "Exports: "
|
std::cout << "Exports: "
|
||||||
<< "\n";
|
<< "\n";
|
||||||
IterExpVA(p, printExps, NULL);
|
IterExpFull(p, printExps, NULL);
|
||||||
|
|
||||||
// read the first 8 bytes from the entry point and print them
|
// read the first 8 bytes from the entry point and print them
|
||||||
VA entryPoint;
|
VA entryPoint;
|
||||||
|
@ -222,13 +222,25 @@ typedef int (*iterSymbol)(void *,
|
|||||||
const std::uint8_t &);
|
const std::uint8_t &);
|
||||||
void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd);
|
void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd);
|
||||||
|
|
||||||
// iterate over the exports
|
// iterate over the exports, except forwarded exports
|
||||||
typedef int (*iterExp)(void *,
|
typedef int (*iterExp)(void *,
|
||||||
const VA &,
|
const VA &,
|
||||||
const std::string &,
|
const std::string &,
|
||||||
const std::string &);
|
const std::string &);
|
||||||
void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd);
|
void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd);
|
||||||
|
|
||||||
|
// iterate over the exports, including forwarded exports
|
||||||
|
// export ordinal is also provided as the third argument.
|
||||||
|
// VA will be zero if the current export is forwarded,
|
||||||
|
// in this case, the last argument (forward string) will be non-empty
|
||||||
|
typedef int (*iterExpFull)(void *,
|
||||||
|
const VA &,
|
||||||
|
std::uint16_t,
|
||||||
|
const std::string &,
|
||||||
|
const std::string &,
|
||||||
|
const std::string &);
|
||||||
|
void IterExpFull(parsed_pe *pe, iterExpFull cb, void *cbd);
|
||||||
|
|
||||||
// iterate over sections
|
// iterate over sections
|
||||||
typedef int (*iterSec)(void *,
|
typedef int (*iterSec)(void *,
|
||||||
const VA &,
|
const VA &,
|
||||||
|
@ -51,8 +51,10 @@ struct importent {
|
|||||||
|
|
||||||
struct exportent {
|
struct exportent {
|
||||||
VA addr;
|
VA addr;
|
||||||
|
std::uint16_t ordinal;
|
||||||
std::string symbolName;
|
std::string symbolName;
|
||||||
std::string moduleName;
|
std::string moduleName;
|
||||||
|
std::string forwardName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reloc {
|
struct reloc {
|
||||||
@ -1670,23 +1672,37 @@ bool getExports(parsed_pe *p) {
|
|||||||
((symRVA >= exportDir.VirtualAddress) &&
|
((symRVA >= exportDir.VirtualAddress) &&
|
||||||
(symRVA < exportDir.VirtualAddress + exportDir.Size));
|
(symRVA < exportDir.VirtualAddress + exportDir.Size));
|
||||||
|
|
||||||
|
VA symVA;
|
||||||
|
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||||
|
symVA = symRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||||
|
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||||
|
symVA = symRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
exportent a;
|
||||||
|
a.ordinal = ordinal;
|
||||||
|
a.symbolName = symName;
|
||||||
|
a.moduleName = modName;
|
||||||
|
|
||||||
if (!isForwarded) {
|
if (!isForwarded) {
|
||||||
VA symVA;
|
a.addr = symVA;
|
||||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
a.forwardName.clear();
|
||||||
symVA = symRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
} else {
|
||||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
section fwdSec;
|
||||||
symVA = symRVA + p->peHeader.nt.OptionalHeader64.ImageBase;
|
if (!getSecForVA(p->internal->secs, symVA, fwdSec)) {
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
auto fwdOff = static_cast<std::uint32_t>(symVA - fwdSec.sectionBase);
|
||||||
|
|
||||||
exportent a;
|
a.addr = 0;
|
||||||
|
if (!readCString(*fwdSec.sectionData, fwdOff, a.forwardName)) {
|
||||||
a.addr = symVA;
|
return false;
|
||||||
a.symbolName = symName;
|
}
|
||||||
a.moduleName = modName;
|
|
||||||
p->internal->exports.push_back(a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->internal->exports.push_back(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2532,6 +2548,9 @@ void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd) {
|
|||||||
std::vector<exportent> &l = pe->internal->exports;
|
std::vector<exportent> &l = pe->internal->exports;
|
||||||
|
|
||||||
for (exportent &i : l) {
|
for (exportent &i : l) {
|
||||||
|
if (i.addr == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (cb(cbd, i.addr, i.moduleName, i.symbolName) != 0) {
|
if (cb(cbd, i.addr, i.moduleName, i.symbolName) != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2540,6 +2559,20 @@ void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iterate over the exports with full information
|
||||||
|
void IterExpFull(parsed_pe *pe, iterExpFull cb, void *cbd) {
|
||||||
|
std::vector<exportent> &l = pe->internal->exports;
|
||||||
|
|
||||||
|
for (exportent &i : l) {
|
||||||
|
if (cb(cbd, i.addr, i.ordinal, i.moduleName, i.symbolName, i.forwardName) !=
|
||||||
|
0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// iterate over sections
|
// iterate over sections
|
||||||
void IterSec(parsed_pe *pe, iterSec cb, void *cbd) {
|
void IterSec(parsed_pe *pe, iterSec cb, void *cbd) {
|
||||||
parsed_pe_internal *pint = pe->internal;
|
parsed_pe_internal *pint = pe->internal;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user