Skip to content

Commit af7637e

Browse files
Added the ability to dump x86 process.
1 parent f5cd80f commit af7637e

5 files changed

Lines changed: 206 additions & 120 deletions

File tree

PEParser/PEParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,8 @@ bool PEParser::SavePEFileToDisk(const WCHAR* pNewFile) {
994994

995995
writeSize = _PESections[i]._sectionHeader.SizeOfRawData;
996996

997+
writeSize = std::min<DWORD>(_PESections[i]._dataSize, writeSize);
998+
997999
if (writeSize) {
9981000
if (!WriteMemoryToFile(_hFile, _PESections[i]._sectionHeader.PointerToRawData,
9991001
writeSize, _PESections[i]._pData)) {

WinArk/ApiReader.cpp

Lines changed: 73 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -161,65 +161,34 @@ void ApiReader::ParseModuleWithOwnProcess(ModuleInfo* pModule) {
161161
}
162162
}
163163

164-
void ApiReader::FindApiInProcess(ModuleInfo* pModule, char* searchName, WORD ordinal, DWORD_PTR* pVA, DWORD_PTR* pRVA) {
164+
void ApiReader::FindApiInProcess(ModuleInfo* pModule, char* pSearchName, WORD ordinal, DWORD_PTR* pVA, DWORD_PTR* pRVA) {
165165
PIMAGE_NT_HEADERS pNtHeader = nullptr;
166166
PIMAGE_DOS_HEADER pDosHeader = nullptr;
167-
BYTE* pPE = nullptr;
168-
PIMAGE_EXPORT_DIRECTORY pExportTable = nullptr;
169-
170-
pPE = GetHeaderFromProcess(pModule);
171-
if (pPE == nullptr)
172-
return;
167+
BYTE* pPE = new BYTE[pModule->_modBaseSize];
173168

174-
pDosHeader = (PIMAGE_DOS_HEADER)pPE;
175-
pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)pPE + pDosHeader->e_lfanew);
176-
if (IsPEAndExportTableValid(pNtHeader)) {
177-
pExportTable = GetExportTableFromProcess(pModule, pNtHeader);
178-
if (pExportTable) {
179-
FindApiInExportTable(pModule, pExportTable,
180-
(DWORD_PTR)pExportTable - pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
181-
searchName, ordinal, pVA, pRVA);
182-
delete[] pExportTable;
183-
}
184-
}
169+
ReadMemoryFromProcess(pModule->_modBaseAddr, pModule->_modBaseSize, pPE);
170+
171+
PEParser parser(pPE);
185172

186-
delete[] pPE;
187-
}
173+
auto exports = parser.GetExports();
188174

189-
bool ApiReader::FindApiInExportTable(ModuleInfo* pModule, PIMAGE_EXPORT_DIRECTORY pExportDir,
190-
DWORD_PTR deltaAddress, char* searchName,WORD ordinal, DWORD_PTR* pVA, DWORD_PTR* pRVA)
191-
{
192-
DWORD* pAddressOfFunctions = nullptr, * pAddressOfNames = nullptr;
193-
WORD* pAddressOfNameOrdinals = nullptr;
194-
char* pFunctionName = nullptr;
195-
196-
pAddressOfFunctions = (DWORD*)((DWORD_PTR)pExportDir->AddressOfFunctions + deltaAddress);
197-
pAddressOfNames = (DWORD*)((DWORD_PTR)pExportDir->AddressOfNames + deltaAddress);
198-
pAddressOfNameOrdinals = (WORD*)((DWORD_PTR)pExportDir->AddressOfNameOrdinals + deltaAddress);
199-
200-
if (searchName) {
201-
for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
202-
pFunctionName = (char*)(pAddressOfNames[i] + deltaAddress);
203-
if (!strcmp(pFunctionName, searchName)) {
204-
*pRVA = pAddressOfFunctions[pAddressOfNameOrdinals[i]];
205-
*pVA = *pRVA + pModule->_modBaseAddr;
206-
return true;
175+
for (ExportedSymbol symbol : exports) {
176+
if (pSearchName != nullptr) {
177+
if (!strcmp(symbol.Name.c_str(), pSearchName)) {
178+
*pVA = symbol.Address + pModule->_modBaseAddr;
179+
*pRVA = symbol.Address;
180+
break;
207181
}
208182
}
209-
}
210-
else {
211-
for (DWORD i = 0; i < pExportDir->NumberOfFunctions; i++)
212-
{
213-
if (ordinal == (i + pExportDir->Base))
214-
{
215-
*pRVA = pAddressOfFunctions[i];
216-
*pVA = *pRVA + pModule->_modBaseAddr;
217-
return true;
218-
}
183+
if (symbol.Ordinal == ordinal) {
184+
*pVA = symbol.Address + pModule->_modBaseAddr;
185+
*pRVA = symbol.Address;
186+
break;
219187
}
220188
}
189+
221190

222-
return false;
191+
delete[] pPE;
223192
}
224193

225194
BYTE* ApiReader::GetHeaderFromProcess(ModuleInfo* pModule)
@@ -685,34 +654,72 @@ void ApiReader::ParseIAT(DWORD_PTR iat, BYTE* pIAT, SIZE_T size) {
685654
ModuleInfo* pModule = nullptr;
686655
bool isSuspect = false;
687656
int countApiFound = 0, countApiNotFound = 0;
688-
DWORD_PTR* pIATAddress = (DWORD_PTR*)pIAT;
689-
SIZE_T iatSize = size / sizeof(DWORD_PTR);
690-
691-
for (SIZE_T i = 0; i < iatSize; i++) {
692-
if (!IsInvalidMemoryForIAT(pIATAddress[i])) {
693-
if (pIATAddress[i] > _minApiAddress && pIATAddress[i] < _maxApiAddress) {
694-
pApiFound = GetApiByVirtualAddress(pIATAddress[i], &isSuspect);
695-
if (pApiFound != nullptr) {
696-
countApiFound++;
697-
if (pModule != pApiFound->pModule) {
698-
pModule = pApiFound->pModule;
699-
AddFoundApiToModuleList(iat + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)pIAT, pApiFound, true, isSuspect);
657+
DWORD_PTR* p64 = (DWORD_PTR*)pIAT;
658+
DWORD* p32 = reinterpret_cast<DWORD*>(pIAT);
659+
SIZE_T iatSize = 0;
660+
DWORD pointerSize = 0;
661+
BOOL isWow64 = FALSE;
662+
::IsWow64Process(_hProcess, &isWow64);
663+
if (isWow64) {
664+
pointerSize = 4;
665+
iatSize = size / pointerSize;
666+
for (SIZE_T i = 0; i < iatSize; i++) {
667+
if (!IsInvalidMemoryForIAT(p32[i])) {
668+
if (p32[i] > _minApiAddress && p32[i] < _maxApiAddress) {
669+
pApiFound = GetApiByVirtualAddress(p32[i], &isSuspect);
670+
if (pApiFound != nullptr) {
671+
countApiFound++;
672+
if (pModule != pApiFound->pModule) {
673+
pModule = pApiFound->pModule;
674+
AddFoundApiToModuleList(iat + (DWORD_PTR)&p32[i] - (DWORD_PTR)pIAT, pApiFound, true, isSuspect);
675+
}
676+
else {
677+
AddFoundApiToModuleList(iat + (DWORD_PTR)&p32[i] - (DWORD_PTR)pIAT, pApiFound, false, isSuspect);
678+
}
700679
}
701680
else {
702-
AddFoundApiToModuleList(iat + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)pIAT, pApiFound, false, isSuspect);
681+
countApiNotFound++;
682+
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&p32[i] - (DWORD_PTR)pIAT, p32[i]);
703683
}
704684
}
705685
else {
706686
countApiNotFound++;
707-
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)pIAT, pIATAddress[i]);
687+
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&p32[i] - (DWORD_PTR)pIAT, p32[i]);
708688
}
709689
}
710-
else {
711-
countApiNotFound++;
712-
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)pIAT, pIATAddress[i]);
690+
}
691+
}
692+
else {
693+
pointerSize = 8;
694+
iatSize = size / pointerSize;
695+
for (SIZE_T i = 0; i < iatSize; i++) {
696+
if (!IsInvalidMemoryForIAT(p64[i])) {
697+
if (p64[i] > _minApiAddress && p64[i] < _maxApiAddress) {
698+
pApiFound = GetApiByVirtualAddress(p64[i], &isSuspect);
699+
if (pApiFound != nullptr) {
700+
countApiFound++;
701+
if (pModule != pApiFound->pModule) {
702+
pModule = pApiFound->pModule;
703+
AddFoundApiToModuleList(iat + (DWORD_PTR)&p64[i] - (DWORD_PTR)pIAT, pApiFound, true, isSuspect);
704+
}
705+
else {
706+
AddFoundApiToModuleList(iat + (DWORD_PTR)&p64[i] - (DWORD_PTR)pIAT, pApiFound, false, isSuspect);
707+
}
708+
}
709+
else {
710+
countApiNotFound++;
711+
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&p64[i] - (DWORD_PTR)pIAT, p64[i]);
712+
}
713+
}
714+
else {
715+
countApiNotFound++;
716+
AddNotFoundApiToModuleList(iat + (DWORD_PTR)&p64[i] - (DWORD_PTR)pIAT, p64[i]);
717+
}
713718
}
714719
}
715720
}
721+
722+
716723
}
717724

718725
void ApiReader::AddApi(const char* pName, WORD hint, WORD ordinal,

WinArk/ApiReader.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ class ApiReader : public ProcessAccessHelper
5050
void ParseModuleWithOwnProcess(ModuleInfo* pModule);
5151
bool IsPEAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader);
5252
void FindApiInProcess(ModuleInfo* pModule, char* searchName, WORD ordinal, DWORD_PTR* pVA, DWORD_PTR* pRVA);
53-
bool FindApiInExportTable(ModuleInfo* pModule, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress,
54-
char* searchName,WORD ordinal,
55-
DWORD_PTR* pVA, DWORD_PTR* pRVA);
5653

5754
BYTE* GetHeaderFromProcess(ModuleInfo* pModule);
5855
PIMAGE_EXPORT_DIRECTORY GetExportTableFromProcess(ModuleInfo* pModule, PIMAGE_NT_HEADERS pNtHeader);

WinArk/IATSearcher.cpp

Lines changed: 103 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,19 @@ bool IATSearcher::FindIATAdvanced(DWORD_PTR startAddress, DWORD_PTR* pIAT, DWORD
6767
*pIAT = start;
6868
iter = iatPointers.end();
6969
DWORD_PTR end = *(--iter);
70-
*pSize = (DWORD)(end - start + sizeof(DWORD_PTR));
7170

72-
if (*pSize > (2000000 * sizeof(DWORD_PTR))) {
71+
BOOL isWow64 = FALSE;
72+
::IsWow64Process(_hProcess, &isWow64);
73+
DWORD pointerSize = 0;
74+
if (isWow64) {
75+
pointerSize = 4;
76+
}
77+
else {
78+
pointerSize = 8;
79+
}
80+
*pSize = (DWORD)(end - start + pointerSize);
81+
82+
if (*pSize > (2000000 * pointerSize)) {
7383
*pIAT = 0;
7484
*pSize = 0;
7585
return false;
@@ -162,7 +172,16 @@ DWORD_PTR IATSearcher::FindIATPointer() {
162172

163173
bool IATSearcher::IsIATPointerValid(DWORD_PTR iatPointer, bool checkRedirects) {
164174
DWORD_PTR apiAddress = 0;
165-
if (!ReadMemoryFromProcess(iatPointer, sizeof(DWORD_PTR), &apiAddress)) {
175+
BOOL isWow64 = FALSE;
176+
::IsWow64Process(_hProcess, &isWow64);
177+
DWORD pointerSize = 0;
178+
if (isWow64) {
179+
pointerSize = 4;
180+
}
181+
else {
182+
pointerSize = 8;
183+
}
184+
if (!ReadMemoryFromProcess(iatPointer, pointerSize, &apiAddress)) {
166185
return false;
167186
}
168187

@@ -193,7 +212,16 @@ bool IATSearcher::FindIATStartAndSize(DWORD_PTR address, DWORD_PTR* pIAT, DWORD*
193212
if (!baseAddress)
194213
return false;
195214

196-
size_t size = baseSize * sizeof(DWORD_PTR) * 3;
215+
BOOL isWow64 = FALSE;
216+
::IsWow64Process(_hProcess, &isWow64);
217+
DWORD pointerSize = 0;
218+
if (isWow64) {
219+
pointerSize = 4;
220+
}
221+
else {
222+
pointerSize = 8;
223+
}
224+
size_t size = baseSize * pointerSize * 3;
197225
buffer = std::make_unique<BYTE[]>(size);
198226

199227
if (!buffer)
@@ -212,48 +240,94 @@ bool IATSearcher::FindIATStartAndSize(DWORD_PTR address, DWORD_PTR* pIAT, DWORD*
212240
}
213241

214242
DWORD_PTR IATSearcher::FindIATStartAddress(DWORD_PTR baseAddress, DWORD_PTR startAddress, BYTE* pData) {
215-
DWORD_PTR* pIATAddress = nullptr;
216-
217-
pIATAddress = (DWORD_PTR*)((startAddress - baseAddress) + (DWORD_PTR)pData);
218-
219-
while ((DWORD_PTR)pIATAddress != (DWORD_PTR)pData) {
220-
if (IsInvalidMemoryForIAT(*pIATAddress)) {
221-
if ((DWORD_PTR)(pIATAddress - 1) >= (DWORD_PTR)pData) {
222-
if (IsInvalidMemoryForIAT(*(pIATAddress - 1))) {
223-
if ((DWORD_PTR)(pIATAddress - 2) >= (DWORD_PTR)pData) {
224-
DWORD_PTR* pIATStart = pIATAddress - 2;
225-
DWORD_PTR apiAddress = *pIATStart;
226-
if (IsApiAddressValid(apiAddress)) {
227-
if (!IsApiAddressValid(*(pIATStart - 1))) {
228-
return (((DWORD_PTR)pIATStart - (DWORD_PTR)pData) + baseAddress);
243+
BOOL isWow64 = FALSE;
244+
::IsWow64Process(_hProcess, &isWow64);
245+
DWORD pointerSize = 0;
246+
if (isWow64) {
247+
DWORD* p32 = nullptr;
248+
249+
p32 = (DWORD*)((startAddress - baseAddress) + (DWORD_PTR)pData);
250+
251+
while ((DWORD_PTR)p32 != (DWORD_PTR)pData) {
252+
if (IsInvalidMemoryForIAT(*p32)) {
253+
if ((DWORD_PTR)(p32 - 1) >= (DWORD_PTR)pData) {
254+
if (IsInvalidMemoryForIAT(*(p32 - 1))) {
255+
if ((DWORD_PTR)(p32 - 2) >= (DWORD_PTR)pData) {
256+
if (!IsApiAddressValid(*(p32 - 2))) {
257+
return (DWORD_PTR)p32 - (DWORD_PTR)pData + baseAddress;
229258
}
230259
}
231260
}
232261
}
233262
}
263+
264+
p32--;
234265
}
266+
}
267+
else {
268+
DWORD_PTR* p64 = nullptr;
269+
270+
p64 = (DWORD_PTR*)((startAddress - baseAddress) + (DWORD_PTR)pData);
271+
272+
while ((DWORD_PTR)p64 != (DWORD_PTR)pData) {
273+
if (IsInvalidMemoryForIAT(*p64)) {
274+
if ((DWORD_PTR)(p64 - 1) >= (DWORD_PTR)pData) {
275+
if (IsInvalidMemoryForIAT(*(p64 - 1))) {
276+
if ((DWORD_PTR)(p64 - 2) >= (DWORD_PTR)pData) {
277+
DWORD_PTR* pIATStart = p64 - 2;
278+
DWORD_PTR apiAddress = *pIATStart;
279+
if (IsApiAddressValid(apiAddress)) {
280+
if (!IsApiAddressValid(*(pIATStart - 1))) {
281+
return (((DWORD_PTR)pIATStart - (DWORD_PTR)pData) + baseAddress);
282+
}
283+
}
284+
}
285+
}
286+
}
287+
}
235288

236-
pIATAddress--;
289+
p64--;
290+
}
237291
}
292+
238293

239294
return baseAddress;
240295
}
241296

242297

243298
DWORD IATSearcher::FindIATSize(DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE* pData, DWORD dataSize) {
244-
DWORD_PTR* pIATAddress = nullptr;
245-
pIATAddress = (DWORD_PTR*)((iatAddress - baseAddress) + (DWORD_PTR)pData);
246-
247-
while ((DWORD_PTR)pIATAddress < ((DWORD_PTR)pData + dataSize - 1)) {
248-
if (IsInvalidMemoryForIAT(*pIATAddress)) {
249-
if (IsInvalidMemoryForIAT(*(pIATAddress + 1))) {
250-
DWORD_PTR apiAddress = *(pIATAddress + 2);
251-
if (!IsApiAddressValid(apiAddress) && apiAddress != 0) {
252-
return (DWORD)((DWORD_PTR)pIATAddress - (DWORD_PTR)pData - (iatAddress - baseAddress));
299+
PBYTE* pIATAddress = nullptr;
300+
pIATAddress = (PBYTE*)((iatAddress - baseAddress) + (DWORD_PTR)pData);
301+
BOOL isWow64 = FALSE;
302+
::IsWow64Process(_hProcess, &isWow64);
303+
DWORD* p32 = (DWORD*)pIATAddress;
304+
DWORD_PTR* p64 = (DWORD_PTR*)pIATAddress;
305+
306+
if (isWow64) {
307+
while ((DWORD_PTR)p32 < ((DWORD_PTR)pData + dataSize - 1)) {
308+
if (IsInvalidMemoryForIAT(*p32)) {
309+
if (IsInvalidMemoryForIAT(*(p32 + 1))) {
310+
DWORD_PTR apiAddress = *(p32 + 2);
311+
if (!IsApiAddressValid(apiAddress) && apiAddress != 0) {
312+
return (DWORD)((DWORD_PTR)p32 - (DWORD_PTR)pData - (iatAddress - baseAddress));
313+
}
314+
}
315+
}
316+
p32++;
317+
}
318+
}
319+
else {
320+
while ((DWORD_PTR)p64 < ((DWORD_PTR)pData + dataSize - 1)) {
321+
if (IsInvalidMemoryForIAT(*p64)) {
322+
if (IsInvalidMemoryForIAT(*(p64 + 1))) {
323+
DWORD_PTR apiAddress = *(p64 + 2);
324+
if (!IsApiAddressValid(apiAddress) && apiAddress != 0) {
325+
return (DWORD)((DWORD_PTR)p64 - (DWORD_PTR)pData - (iatAddress - baseAddress));
326+
}
253327
}
254328
}
329+
p64++;
255330
}
256-
pIATAddress++;
257331
}
258332

259333
return dataSize;

0 commit comments

Comments
 (0)