mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-04-26 04:14:32 +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 <iomanip>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
@ -35,19 +36,34 @@ using namespace peparse;
|
||||
|
||||
int printExps(void *N,
|
||||
const VA &funcAddr,
|
||||
std::uint16_t ordinal,
|
||||
const std::string &mod,
|
||||
const std::string &func) {
|
||||
const std::string &func,
|
||||
const std::string &fwd) {
|
||||
static_cast<void>(N);
|
||||
|
||||
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 << "!";
|
||||
std::cout << func;
|
||||
std::cout << ": 0x";
|
||||
std::cout << std::hex << address;
|
||||
std::cout << ": ";
|
||||
if (!fwd.empty()) {
|
||||
std::cout << fwd;
|
||||
} else {
|
||||
std::cout << std::showbase << std::hex << address;
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
// restore default formatting
|
||||
std::cout.copyfmt(initial);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -440,7 +456,7 @@ int main(int argc, char *argv[]) {
|
||||
IterSec(p, printSecs, NULL);
|
||||
std::cout << "Exports: "
|
||||
<< "\n";
|
||||
IterExpVA(p, printExps, NULL);
|
||||
IterExpFull(p, printExps, NULL);
|
||||
|
||||
// read the first 8 bytes from the entry point and print them
|
||||
VA entryPoint;
|
||||
|
@ -222,13 +222,25 @@ typedef int (*iterSymbol)(void *,
|
||||
const std::uint8_t &);
|
||||
void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd);
|
||||
|
||||
// iterate over the exports
|
||||
// iterate over the exports, except forwarded exports
|
||||
typedef int (*iterExp)(void *,
|
||||
const VA &,
|
||||
const std::string &,
|
||||
const std::string &);
|
||||
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
|
||||
typedef int (*iterSec)(void *,
|
||||
const VA &,
|
||||
|
@ -51,8 +51,10 @@ struct importent {
|
||||
|
||||
struct exportent {
|
||||
VA addr;
|
||||
std::uint16_t ordinal;
|
||||
std::string symbolName;
|
||||
std::string moduleName;
|
||||
std::string forwardName;
|
||||
};
|
||||
|
||||
struct reloc {
|
||||
@ -1670,7 +1672,6 @@ bool getExports(parsed_pe *p) {
|
||||
((symRVA >= exportDir.VirtualAddress) &&
|
||||
(symRVA < exportDir.VirtualAddress + exportDir.Size));
|
||||
|
||||
if (!isForwarded) {
|
||||
VA symVA;
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
symVA = symRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
@ -1681,12 +1682,27 @@ bool getExports(parsed_pe *p) {
|
||||
}
|
||||
|
||||
exportent a;
|
||||
|
||||
a.addr = symVA;
|
||||
a.ordinal = ordinal;
|
||||
a.symbolName = symName;
|
||||
a.moduleName = modName;
|
||||
p->internal->exports.push_back(a);
|
||||
|
||||
if (!isForwarded) {
|
||||
a.addr = symVA;
|
||||
a.forwardName.clear();
|
||||
} else {
|
||||
section fwdSec;
|
||||
if (!getSecForVA(p->internal->secs, symVA, fwdSec)) {
|
||||
return false;
|
||||
}
|
||||
auto fwdOff = static_cast<std::uint32_t>(symVA - fwdSec.sectionBase);
|
||||
|
||||
a.addr = 0;
|
||||
if (!readCString(*fwdSec.sectionData, fwdOff, a.forwardName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for (exportent &i : l) {
|
||||
if (i.addr == 0) {
|
||||
continue;
|
||||
}
|
||||
if (cb(cbd, i.addr, i.moduleName, i.symbolName) != 0) {
|
||||
break;
|
||||
}
|
||||
@ -2540,6 +2559,20 @@ void IterExpVA(parsed_pe *pe, iterExp cb, void *cbd) {
|
||||
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
|
||||
void IterSec(parsed_pe *pe, iterSec cb, void *cbd) {
|
||||
parsed_pe_internal *pint = pe->internal;
|
||||
|
Loading…
x
Reference in New Issue
Block a user