00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if defined(_MSC_VER) && _MSC_VER <= 1200
00029 #pragma warning(disable:4786)
00030 #endif
00031 #if defined(_MSC_VER) && _MSC_VER >= 1400
00032 #pragma warning(disable:4996) // Warnings about e.g. _strdup deprecated in VS 2005
00033 #endif
00034
00035 #ifdef _WIN32
00036 #include <windows.h>
00037 #ifndef __MINGW32__
00038 namespace dbghelp {
00039 #include <dbghelp.h>
00040 };
00041 #endif
00042 #endif
00043
00044 #include "BinaryFile.h"
00045 #include "Win32BinaryFile.h"
00046 #include "config.h"
00047 #include <iostream>
00048 #include <sstream>
00049 #include <assert.h>
00050
00051 extern "C" {
00052 int microX86Dis(void* p);
00053 }
00054
00055
00056 #ifndef IMAGE_SCN_CNT_CODE // Assume that if one is not defined, the rest isn't either.
00057 #define IMAGE_SCN_CNT_CODE 0x00000020
00058 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
00059 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
00060 #define IMAGE_SCN_MEM_READ 0x40000000
00061 #define IMAGE_SCN_MEM_WRITE 0x80000000
00062 #endif
00063
00064
00065 namespace {
00066
00067
00068
00069
00070
00071
00072
00073 typedef std::map<const class PESectionInfo*, const PEObject*> SectionObjectMap;
00074
00075 SectionObjectMap s_sectionObjects;
00076
00077
00078
00079
00080 class PESectionInfo : public SectionInfo
00081 {
00082 virtual bool isAddressBss(ADDRESS a) const
00083 {
00084 if (a < uNativeAddr || a >= uNativeAddr + uSectionSize) {
00085 return false;
00086 }
00087 if (bBss) {
00088 return true;
00089 }
00090 if (bReadOnly) {
00091 return false;
00092 }
00093
00094 const SectionObjectMap::iterator it = s_sectionObjects.find(this);
00095 assert(it != s_sectionObjects.end());
00096 assert(it->second);
00097 assert(this == it->first);
00098 const PEObject* sectionHeader = it->second;
00099 const bool has_slack = LMMH(sectionHeader->VirtualSize) > LMMH(sectionHeader->PhysicalSize);
00100 if (!has_slack) {
00101 return false;
00102 }
00103 if (a >= uNativeAddr + LMMH(sectionHeader->PhysicalSize)) {
00104 return true;
00105 }
00106 return false;
00107 }
00108 };
00109
00110
00111
00112 typedef char ct_failure[sizeof(SectionInfo) == sizeof(PESectionInfo)];
00113
00114 }
00115
00116
00117 Win32BinaryFile::Win32BinaryFile() : m_pFileName(0), mingw_main(false)
00118 { }
00119
00120 Win32BinaryFile::~Win32BinaryFile()
00121 {
00122 for (int i=0; i < m_iNumSections; i++) {
00123 if (m_pSections[i].pSectionName)
00124 delete [] m_pSections[i].pSectionName;
00125 }
00126 if (m_pSections) delete [] m_pSections;
00127 }
00128
00129 bool Win32BinaryFile::Open(const char* sName) {
00130
00131 return false;
00132 }
00133
00134 void Win32BinaryFile::Close() {
00135 UnLoad();
00136 }
00137
00138 std::list<SectionInfo*>& Win32BinaryFile::GetEntryPoints(
00139 const char* pEntry)
00140 {
00141 fprintf(stderr,"really don't know how to implement GetEntryPoints\n");
00142 exit(0);
00143 static std::list<SectionInfo*> l;
00144 return l;
00145 }
00146
00147 ADDRESS Win32BinaryFile::GetEntryPoint()
00148 {
00149 return (ADDRESS)(LMMH(m_pPEHeader->EntrypointRVA) +
00150 LMMH(m_pPEHeader->Imagebase));
00151 }
00152
00153
00154
00155
00156 ADDRESS Win32BinaryFile::GetMainEntryPoint() {
00157 ADDRESS aMain = GetAddressByName ("main", true);
00158 if (aMain != NO_ADDRESS)
00159 return aMain;
00160 aMain = GetAddressByName ("_main", true);
00161 if (aMain != NO_ADDRESS)
00162 return aMain;
00163
00164
00165 unsigned p = LMMH(m_pPEHeader->EntrypointRVA);
00166 unsigned lim = p + 0x200;
00167 unsigned char op1, op2;
00168 unsigned addr, lastOrdCall = 0;
00169 int gap;
00170 int borlandState = 0;
00171
00172 SectionInfo* si = GetSectionInfoByName(".text");
00173 if (si == NULL) si = GetSectionInfoByName("CODE");
00174 assert(si);
00175 unsigned textSize = si->uSectionSize;
00176 if (textSize < 0x200)
00177 lim = p + textSize;
00178
00179 if (m_pPEHeader->Subsystem == 1)
00180 return LMMH(m_pPEHeader->EntrypointRVA) + LMMH(m_pPEHeader->Imagebase);
00181
00182 gap = 0xF0000000;
00183 while (p < lim) {
00184 op1 = *(unsigned char*)(p + base);
00185 op2 = *(unsigned char*)(p + base + 1);
00186
00187 switch (op1) {
00188 case 0xE8: {
00189
00190 lastOrdCall = p;
00191 gap = 0;
00192 if (borlandState == 1)
00193 borlandState++;
00194 else
00195 borlandState = 0;
00196 break;
00197 }
00198 case 0xFF:
00199 if (op2 == 0x15) {
00200
00201 addr = LMMH(*(p + base + 2));
00202
00203
00204 if (dlprocptrs[addr] == "exit") {
00205 if (gap <= 10) {
00206
00207 addr = LMMH(*(lastOrdCall + base + 1));
00208 addr += lastOrdCall + 5;
00209
00210 return addr + LMMH(m_pPEHeader->Imagebase);
00211 }
00212 }
00213 } else
00214 borlandState = 0;
00215 break;
00216 case 0xEB:
00217 if (op2 >= 0x80)
00218 break;
00219
00220 p += op2+2;
00221 gap++;
00222 continue;
00223 case 0x6A:
00224 if (op2 == 0) {
00225
00226
00227 if (borlandState == 0)
00228 borlandState = 1;
00229 else if (borlandState == 4) {
00230
00231 ADDRESS mainInfo = LMMH(*(base + p-4));
00232 ADDRESS main = readNative4(mainInfo+0x18);
00233 return main;
00234 }
00235 } else
00236 borlandState = 0;
00237 break;
00238 case 0x59:
00239 if (borlandState == 2)
00240 borlandState = 3;
00241 else
00242 borlandState = 0;
00243 break;
00244 case 0x68:
00245 if (borlandState == 3)
00246 borlandState++;
00247 else
00248 borlandState = 0;
00249 break;
00250 default:
00251 borlandState = 0;
00252 break;
00253 }
00254 int size = microX86Dis(p + base);
00255 if (size == 0x40) {
00256 fprintf(stderr, "Warning! Microdisassembler out of step at offset 0x%x\n", p);
00257 size = 1;
00258 }
00259 p += size;
00260 gap++;
00261 }
00262
00263
00264 p = LMMH(m_pPEHeader->EntrypointRVA);
00265 if (*(unsigned char*)(p + base + 0x20) == 0xff && *(unsigned char*)(p + base + 0x21) == 0x15) {
00266 unsigned int desti = LMMH(*(p + base + 0x22));
00267 if (dlprocptrs.find(desti) != dlprocptrs.end() && dlprocptrs[desti] == "GetVersionExA") {
00268 if (*(unsigned char*)(p + base + 0x6d) == 0xff && *(unsigned char*)(p + base + 0x6e) == 0x15) {
00269 desti = LMMH(*(p + base + 0x6f));
00270 if (dlprocptrs.find(desti) != dlprocptrs.end() && dlprocptrs[desti] == "GetModuleHandleA") {
00271 if (*(unsigned char*)(p + base + 0x16e) == 0xe8) {
00272 unsigned int dest = p + 0x16e + 5 + LMMH(*(p + base + 0x16f));
00273 return dest + LMMH(m_pPEHeader->Imagebase);
00274 }
00275 }
00276 }
00277 }
00278 }
00279
00280
00281 int count = 100;
00282 int pushes = 0;
00283 p = LMMH(m_pPEHeader->EntrypointRVA);
00284 while (count > 0) {
00285 count--;
00286 op1 = *(unsigned char*)(p + base);
00287 if (op1 == 0xE8) {
00288 if (pushes == 3) {
00289
00290 int off = LMMH(*(p + base + 1));
00291 unsigned dest = (unsigned)p + 5 + off;
00292
00293 op1 = *(unsigned char*)(dest + base);
00294 if (op1 == 0xE9) {
00295
00296 off = LMMH(*(dest + base + 1));
00297 dest = dest + 5 + off;
00298 }
00299 return dest + LMMH(m_pPEHeader->Imagebase);
00300 } else
00301 pushes = 0;
00302 }
00303 else if (op1 >= 0x50 && op1 <= 0x57)
00304 pushes++;
00305 else if (op1 == 0xFF) {
00306
00307 op2 = *(unsigned char*)(p + 1 + base);
00308 if (op2 == 0x35)
00309 pushes++;
00310 }
00311 else if (op1 == 0xE9) {
00312
00313 int off = LMMH(*(p + base + 1));
00314 p += off+5;
00315 continue;
00316 }
00317
00318
00319 int size = microX86Dis(p + base);
00320 if (size == 0x40) {
00321 fprintf(stderr, "Warning! Microdisassembler out of step at offset 0x%x\n", p);
00322 size = 1;
00323 }
00324 p += size;
00325 if (p >= textSize)
00326 break;
00327 }
00328
00329
00330 p = LMMH(m_pPEHeader->EntrypointRVA);
00331 bool in_mingw_CRTStartup = false;
00332 unsigned int lastcall = 0, lastlastcall = 0;
00333 while(1) {
00334 op1 = *(unsigned char*)(p + base);
00335 if (op1 == 0xE8) {
00336 unsigned int dest = p + 5 + LMMH(*(p + base + 1));
00337 if (in_mingw_CRTStartup) {
00338 op2 = *(unsigned char*)(dest + base);
00339 unsigned char op2a = *(unsigned char*)(dest + base + 1);
00340 unsigned int desti = LMMH(*(dest + base + 2));
00341
00342
00343 if (op2 == 0xff && op2a == 0x25 && dlprocptrs.find(desti) != dlprocptrs.end() && dlprocptrs[desti] == "ExitProcess") {
00344 mingw_main = true;
00345 return lastlastcall + 5 + LMMH(*(lastlastcall + base + 1)) + LMMH(m_pPEHeader->Imagebase);
00346 }
00347 lastlastcall = lastcall;
00348 lastcall = p;
00349 } else {
00350 p = dest;
00351 in_mingw_CRTStartup = true;
00352 continue;
00353 }
00354 }
00355
00356 int size = microX86Dis(p + base);
00357 if (size == 0x40) {
00358 fprintf(stderr, "Warning! Microdisassembler out of step at offset 0x%x\n", p);
00359 size = 1;
00360 }
00361 p += size;
00362 if (p >= textSize)
00363 break;
00364 }
00365
00366
00367 p = LMMH(m_pPEHeader->EntrypointRVA);
00368 bool gotGMHA = false;
00369 while(1) {
00370 op1 = *(unsigned char*)(p + base);
00371 op2 = *(unsigned char*)(p + base + 1);
00372 if (op1 == 0xFF && op2 == 0x15) {
00373 unsigned int desti = LMMH(*(p + base + 2));
00374 if (dlprocptrs.find(desti) != dlprocptrs.end() && dlprocptrs[desti] == "GetModuleHandleA") {
00375 gotGMHA = true;
00376 }
00377 }
00378 if (op1 == 0xE8 && gotGMHA) {
00379 unsigned int dest = p + 5 + LMMH(*(p + base + 1));
00380 AddSymbol(dest + LMMH(m_pPEHeader->Imagebase), "WinMain");
00381 return dest + LMMH(m_pPEHeader->Imagebase);
00382 }
00383 if (op1 == 0xc3)
00384 break;
00385
00386 int size = microX86Dis(p + base);
00387 if (size == 0x40) {
00388 fprintf(stderr, "Warning! Microdisassembler out of step at offset 0x%x\n", p);
00389 size = 1;
00390 }
00391 p += size;
00392 if (p >= textSize)
00393 break;
00394 }
00395
00396 return NO_ADDRESS;
00397 }
00398
00399 #if defined(_WIN32) && !defined(__MINGW32__)
00400 BOOL CALLBACK lookforsource(
00401 dbghelp::PSOURCEFILE pSourceFile,
00402 PVOID UserContext
00403 )
00404 {
00405 *(bool*)UserContext = true;
00406 return FALSE;
00407 }
00408 #endif
00409
00410 bool Win32BinaryFile::RealLoad(const char* sName)
00411 {
00412 m_pFileName = sName;
00413 FILE *fp = fopen(sName,"rb");
00414
00415 DWord peoffLE, peoff;
00416 fseek(fp, 0x3c, SEEK_SET);
00417 fread(&peoffLE, 4, 1, fp);
00418 peoff = LMMH(peoffLE);
00419
00420 PEHeader tmphdr;
00421
00422 fseek(fp, peoff, SEEK_SET);
00423 fread(&tmphdr, sizeof(tmphdr), 1, fp);
00424
00425
00426 base = (char *)malloc(LMMH(tmphdr.ImageSize));
00427
00428 if (!base) {
00429 fprintf(stderr,"Cannot allocate memory for copy of image\n");
00430 return false;
00431 }
00432
00433 fseek(fp, 0, SEEK_SET);
00434
00435 fread(base, LMMH(tmphdr.HeaderSize), 1, fp);
00436
00437 m_pHeader = (Header *)base;
00438 if (m_pHeader->sigLo!='M' || m_pHeader->sigHi!='Z') {
00439 fprintf(stderr,"error loading file %s, bad magic\n", sName);
00440 return false;
00441 }
00442
00443 m_pPEHeader = (PEHeader *)(base+peoff);
00444 if (m_pPEHeader->sigLo!='P' || m_pPEHeader->sigHi!='E') {
00445 fprintf(stderr,"error loading file %s, bad PE magic\n", sName);
00446 return false;
00447 }
00448
00449
00450
00451 const PEObject *o = (PEObject *)(((char *)m_pPEHeader) + LH(&m_pPEHeader->NtHdrSize) + 24);
00452 m_iNumSections = LH(&m_pPEHeader->numObjects);
00453 m_pSections = new PESectionInfo[m_iNumSections];
00454
00455 for (int i=0; i<m_iNumSections; i++, o++) {
00456 SectionInfo& sect = m_pSections[i];
00457
00458
00459 sect.pSectionName = new char[9];
00460 strncpy(sect.pSectionName, o->ObjectName, 8);
00461
00462
00463 sect.uNativeAddr=(ADDRESS)(LMMH(o->RVA) + LMMH(m_pPEHeader->Imagebase));
00464 sect.uHostAddr=(ADDRESS)(LMMH(o->RVA) + base);
00465 sect.uSectionSize=LMMH(o->VirtualSize);
00466 DWord Flags = LMMH(o->Flags);
00467 sect.bBss = (Flags&IMAGE_SCN_CNT_UNINITIALIZED_DATA)?1:0;
00468 sect.bCode = (Flags&IMAGE_SCN_CNT_CODE)?1:0;
00469 sect.bData = (Flags&IMAGE_SCN_CNT_INITIALIZED_DATA)?1:0;
00470 sect.bReadOnly = (Flags&IMAGE_SCN_MEM_WRITE)?0:1;
00471
00472 fseek(fp, LMMH(o->PhysicalOffset), SEEK_SET);
00473 memset(base + LMMH(o->RVA), 0, LMMH(o->VirtualSize));
00474 fread(base + LMMH(o->RVA), LMMH(o->PhysicalSize), 1, fp);
00475 s_sectionObjects[static_cast<const PESectionInfo*>(§)] = o;
00476 }
00477
00478
00479 PEImportDtor* id = (PEImportDtor*) (LMMH(m_pPEHeader->ImportTableRVA) + base);
00480 if (m_pPEHeader->ImportTableRVA) {
00481 while (id->name != 0) {
00482 char* dllName = LMMH(id->name) + base;
00483 unsigned thunk = id->originalFirstThunk ? id->originalFirstThunk : id->firstThunk;
00484 unsigned* iat = (unsigned*)(LMMH(thunk) + base);
00485 unsigned iatEntry = LMMH(*iat);
00486 ADDRESS paddr = LMMH(id->firstThunk) + LMMH(m_pPEHeader->Imagebase);
00487 while (iatEntry) {
00488 if (iatEntry >> 31) {
00489
00490 std::ostringstream ost;
00491 std::string nodots(dllName);
00492 int len = nodots.size();
00493 for (int j=0; j < len; j++)
00494 if (nodots[j] == '.')
00495 nodots[j] = '_';
00496 ost << nodots << "_" << (iatEntry & 0x7FFFFFFF);
00497 dlprocptrs[paddr] = ost.str();
00498
00499 } else {
00500
00501 std::string name((const char*)(iatEntry+2+base));
00502 dlprocptrs[paddr] = name;
00503 if ((unsigned)paddr != (unsigned)iat - (unsigned)base + LMMH(m_pPEHeader->Imagebase))
00504 dlprocptrs[(unsigned)iat - (unsigned)base + LMMH(m_pPEHeader->Imagebase)]
00505 = std::string("old_") + name;
00506
00507
00508
00509 }
00510 iat++;
00511 iatEntry = LMMH(*iat);
00512 paddr+=4;
00513 }
00514 id++;
00515 }
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525 ADDRESS entry = GetMainEntryPoint();
00526 if (entry != NO_ADDRESS) {
00527 std::map<ADDRESS, std::string>::iterator it = dlprocptrs.find(entry);
00528 if (it == dlprocptrs.end())
00529 dlprocptrs[entry] = "main";
00530 }
00531
00532
00533
00534 ADDRESS start = GetEntryPoint();
00535 findJumps(start);
00536
00537 fclose(fp);
00538
00539 #if defined(_WIN32) && !defined(__MINGW32__)
00540
00541
00542 DWORD error;
00543 HANDLE hProcess;
00544
00545 hProcess = GetCurrentProcess();
00546
00547
00548 dbghelp::SymSetOptions(SYMOPT_LOAD_LINES);
00549
00550 if (dbghelp::SymInitialize(hProcess, NULL, FALSE))
00551 {
00552
00553 }
00554 else
00555 {
00556
00557 error = GetLastError();
00558 printf("SymInitialize returned error : %d\n", error);
00559 return true;
00560 }
00561
00562 DWORD64 dwBaseAddr = 0;
00563
00564 if (dwBaseAddr = dbghelp::SymLoadModule64(hProcess, NULL, (PSTR)sName, NULL, dwBaseAddr, 0))
00565 {
00566 assert(dwBaseAddr == m_pPEHeader->Imagebase);
00567 bool found = false;
00568 dbghelp::SymEnumSourceFiles(hProcess, dwBaseAddr, 0, lookforsource, &found);
00569 haveDebugInfo = found;
00570 }
00571 else
00572 {
00573
00574 error = GetLastError();
00575 printf("SymLoadModule64 returned error : %d\n", error);
00576 return true;
00577 }
00578 #endif
00579
00580 return true;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590 void Win32BinaryFile::findJumps(ADDRESS curr) {
00591 int cnt = 0;
00592 SectionInfo* sec = GetSectionInfoByName(".text");
00593 if (sec == NULL) sec = GetSectionInfoByName("CODE");
00594 assert(sec);
00595
00596 int delta = sec->uHostAddr - sec->uNativeAddr;
00597 while (cnt < 0x60) {
00598 curr -= 2;
00599 cnt += 2;
00600 if (LH(delta+curr) != 0xFF + (0x25<<8)) continue;
00601 ADDRESS operand = LMMH2(delta+curr+2);
00602 std::map<ADDRESS, std::string>::iterator it;
00603 it = dlprocptrs.find(operand);
00604 if (it == dlprocptrs.end()) continue;
00605 std::string sym = it->second;
00606 dlprocptrs[operand] = "__imp_" + sym;
00607 dlprocptrs[curr] = sym;
00608
00609 curr -= 4;
00610 cnt = 0;
00611 }
00612 }
00613
00614
00615 void Win32BinaryFile::UnLoad()
00616 {
00617 }
00618
00619 bool Win32BinaryFile::PostLoad(void* handle)
00620 {
00621 return false;
00622 }
00623
00624 #if defined(_WIN32) && !defined(__MINGW32__)
00625
00626 char *SymTagEnums[] = { "SymTagNull",
00627 "SymTagExe",
00628 "SymTagCompiland",
00629 "SymTagCompilandDetails",
00630 "SymTagCompilandEnv",
00631 "SymTagFunction",
00632 "SymTagBlock",
00633 "SymTagData",
00634 "SymTagAnnotation",
00635 "SymTagLabel",
00636 "SymTagPublicSymbol",
00637 "SymTagUDT",
00638 "SymTagEnum",
00639 "SymTagFunctionType",
00640 "SymTagPointerType",
00641 "SymTagArrayType",
00642 "SymTagBaseType",
00643 "SymTagTypedef",
00644 "SymTagBaseClass",
00645 "SymTagFriend",
00646 "SymTagFunctionArgType",
00647 "SymTagFuncDebugStart",
00648 "SymTagFuncDebugEnd",
00649 "SymTagUsingNamespace",
00650 "SymTagVTableShape",
00651 "SymTagVTable",
00652 "SymTagCustom",
00653 "SymTagThunk",
00654 "SymTagCustomType",
00655 "SymTagManagedType",
00656 "SymTagDimension"
00657 };
00658
00659 enum SymTagEnum
00660 {
00661 SymTagNull,
00662 SymTagExe,
00663 SymTagCompiland,
00664 SymTagCompilandDetails,
00665 SymTagCompilandEnv,
00666 SymTagFunction,
00667 SymTagBlock,
00668 SymTagData,
00669 SymTagAnnotation,
00670 SymTagLabel,
00671 SymTagPublicSymbol,
00672 SymTagUDT,
00673 SymTagEnum,
00674 SymTagFunctionType,
00675 SymTagPointerType,
00676 SymTagArrayType,
00677 SymTagBaseType,
00678 SymTagTypedef,
00679 SymTagBaseClass,
00680 SymTagFriend,
00681 SymTagFunctionArgType,
00682 SymTagFuncDebugStart,
00683 SymTagFuncDebugEnd,
00684 SymTagUsingNamespace,
00685 SymTagVTableShape,
00686 SymTagVTable,
00687 SymTagCustom,
00688 SymTagThunk,
00689 SymTagCustomType,
00690 SymTagManagedType,
00691 SymTagDimension
00692 };
00693
00694 char *basicTypes[] =
00695 {
00696 "notype",
00697 "void",
00698 "char",
00699 "WCHAR",
00700 "??",
00701 "??",
00702 "int",
00703 "unsigned int",
00704 "float",
00705 "bcd",
00706 "bool",
00707 "??",
00708 "??",
00709 "long"
00710 "unsigned long",
00711 };
00712
00713 void printType(DWORD index, DWORD64 ImageBase)
00714 {
00715 HANDLE hProcess = GetCurrentProcess();
00716
00717 int got;
00718 WCHAR *name;
00719 got = dbghelp::SymGetTypeInfo(hProcess, ImageBase, index, dbghelp::TI_GET_SYMNAME, &name);
00720 if (got) {
00721 char nameA[1024];
00722 WideCharToMultiByte(CP_ACP,0,name,-1,nameA,sizeof(nameA),0,NULL);
00723 std::cout << nameA;
00724 return;
00725 }
00726
00727 DWORD d;
00728 got = dbghelp::SymGetTypeInfo(hProcess, ImageBase, index, dbghelp::TI_GET_SYMTAG, &d);
00729 assert(got);
00730
00731 switch(d) {
00732 case SymTagPointerType:
00733 {
00734 got = dbghelp::SymGetTypeInfo(hProcess, ImageBase, index, dbghelp::TI_GET_TYPE, &d);
00735 assert(got);
00736 printType(d, ImageBase);
00737 std::cout << "*";
00738 }
00739 break;
00740 case SymTagBaseType:
00741 got = dbghelp::SymGetTypeInfo(hProcess, ImageBase, index, dbghelp::TI_GET_BASETYPE, &d);
00742 assert(got);
00743 std::cout << basicTypes[d];
00744 break;
00745 default:
00746 std::cerr << "unhandled symtag " << SymTagEnums[d] << "\n";
00747 assert(false);
00748 }
00749
00750 }
00751
00752 BOOL CALLBACK printem(
00753 dbghelp::PSYMBOL_INFO pSymInfo,
00754 ULONG SymbolSize,
00755 PVOID UserContext
00756 )
00757 {
00758 HANDLE hProcess = GetCurrentProcess();
00759 printType(pSymInfo->TypeIndex, pSymInfo->ModBase);
00760 std::cout << " " << pSymInfo->Name << " flags: ";
00761 if (pSymInfo->Flags & SYMFLAG_VALUEPRESENT)
00762 std::cout << "value present, ";
00763 if (pSymInfo->Flags & SYMFLAG_REGISTER)
00764 std::cout << "register, ";
00765 if (pSymInfo->Flags & SYMFLAG_REGREL)
00766 std::cout << "regrel, ";
00767 if (pSymInfo->Flags & SYMFLAG_FRAMEREL)
00768 std::cout << "framerel, ";
00769 if (pSymInfo->Flags & SYMFLAG_PARAMETER)
00770 std::cout << "parameter, ";
00771 if (pSymInfo->Flags & SYMFLAG_LOCAL)
00772 std::cout << "local, ";
00773 if (pSymInfo->Flags & SYMFLAG_CONSTANT)
00774 std::cout << "constant, ";
00775 if (pSymInfo->Flags & SYMFLAG_EXPORT)
00776 std::cout << "export, ";
00777 if (pSymInfo->Flags & SYMFLAG_FORWARDER)
00778 std::cout << "forwarder, ";
00779 if (pSymInfo->Flags & SYMFLAG_FUNCTION)
00780 std::cout << "function, ";
00781 if (pSymInfo->Flags & SYMFLAG_VIRTUAL)
00782 std::cout << "virtual, ";
00783 if (pSymInfo->Flags & SYMFLAG_THUNK)
00784 std::cout << "thunk, ";
00785 if (pSymInfo->Flags & SYMFLAG_TLSREL)
00786 std::cout << "tlsrel, ";
00787 std::cout << "\n";
00788 std::cout << "register: " << pSymInfo->Register << " address: " << (int)pSymInfo->Address << "\n";
00789 return TRUE;
00790 }
00791 #endif
00792
00793 const char* Win32BinaryFile::SymbolByAddress(ADDRESS dwAddr)
00794 {
00795 if (m_pPEHeader->Subsystem == 1 &&
00796 LMMH(m_pPEHeader->EntrypointRVA) + LMMH(m_pPEHeader->Imagebase) == dwAddr)
00797 return "DriverEntry";
00798
00799 if (IsMinGWsAllocStack(dwAddr))
00800 return "__mingw_allocstack";
00801 if (IsMinGWsFrameInit(dwAddr))
00802 return "__mingw_frame_init";
00803 if (IsMinGWsFrameEnd(dwAddr))
00804 return "__mingw_frame_end";
00805 if (IsMinGWsCleanupSetup(dwAddr))
00806 return "__mingw_cleanup_setup";
00807 if (IsMinGWsMalloc(dwAddr))
00808 return "malloc";
00809
00810 #if defined(_WIN32) && !defined(__MINGW32__)
00811 HANDLE hProcess = GetCurrentProcess();
00812 dbghelp::SYMBOL_INFO *sym = (dbghelp::SYMBOL_INFO *)malloc(sizeof(dbghelp::SYMBOL_INFO) + 1000);
00813 sym->SizeOfStruct = sizeof(*sym);
00814 sym->MaxNameLen = 1000;
00815 sym->Name[0] = 0;
00816 BOOL got = dbghelp::SymFromAddr(hProcess, dwAddr, 0, sym);
00817 if (*sym->Name) {
00818 char *n = strdup(sym->Name);
00819 #if 0
00820 std::cout << "found symbol " << n << " for address " << dwAddr << "\n";
00821 std::cout << "typeindex: " << sym->TypeIndex << "\n";
00822 DWORD d = 0;
00823 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, sym->TypeIndex, dbghelp::TI_GET_SYMTAG, &d);
00824 std::cout << "symtag: " << d << "\n";
00825 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, sym->TypeIndex, dbghelp::TI_GET_CALLING_CONVENTION, &d);
00826 std::cout << "calling convention: " << d << "\n";
00827 DWORD my_typeid;
00828 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, sym->TypeIndex, dbghelp::TI_GET_TYPEID, &my_typeid);
00829 std::cout << "typeid: " << my_typeid << "\n";
00830 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_SYMTAG, &d);
00831 std::cout << "symtag: " << d << " ";
00832 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_BASETYPE, &d);
00833 std::cout << "basetype: " << d << " ";
00834 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_TYPE, &d);
00835 std::cout << "type: " << d << "\n";
00836 DWORD count = 0;
00837 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, sym->TypeIndex, dbghelp::TI_GET_CHILDRENCOUNT, &count);
00838 std::cout << "num children: " << count << "\n";
00839 int FindChildrenSize = sizeof(dbghelp::TI_FINDCHILDREN_PARAMS) + count*sizeof(ULONG);
00840 dbghelp::TI_FINDCHILDREN_PARAMS* pFC = (dbghelp::TI_FINDCHILDREN_PARAMS*)malloc( FindChildrenSize );
00841 memset( pFC, 0, FindChildrenSize );
00842 pFC->Count = count;
00843 got = SymGetTypeInfo( hProcess, m_pPEHeader->Imagebase, sym->TypeIndex, dbghelp::TI_FINDCHILDREN, pFC );
00844 for (int i = 0; i < count; i++) {
00845 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, pFC->ChildId[i], dbghelp::TI_GET_TYPEID, &my_typeid);
00846 std::cout << " child: " << pFC->ChildId[i] << " typeid: " << my_typeid << " ";
00847 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_SYMTAG, &d);
00848 std::cout << "symtag: " << d << " ";
00849 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_BASETYPE, &d);
00850 std::cout << "basetype: " << d << " ";
00851 got = dbghelp::SymGetTypeInfo(hProcess, m_pPEHeader->Imagebase, my_typeid, dbghelp::TI_GET_TYPE, &d);
00852 std::cout << "type: " << d << "\n";
00853 }
00854
00855 dbghelp::IMAGEHLP_STACK_FRAME stack;
00856 stack.InstructionOffset = dwAddr;
00857 dbghelp::SymSetContext(hProcess, &stack, 0);
00858 dbghelp::SymEnumSymbols(hProcess, 0, NULL, printem, 0);
00859 #endif
00860 free(sym);
00861 return n;
00862 } else if (IsJumpToAnotherAddr(dwAddr) != NO_ADDRESS)
00863 return SymbolByAddress(IsJumpToAnotherAddr(dwAddr));
00864 #endif
00865
00866 std::map<ADDRESS, std::string>::iterator it = dlprocptrs.find(dwAddr);
00867 if (it == dlprocptrs.end())
00868 return 0;
00869 return (char*) it->second.c_str();
00870 }
00871
00872 ADDRESS Win32BinaryFile::GetAddressByName(const char* pName,
00873 bool bNoTypeOK ) {
00874
00875 std::map<ADDRESS, std::string>::iterator it = dlprocptrs.begin();
00876 while (it != dlprocptrs.end()) {
00877
00878 if (strcmp(it->second.c_str(), pName) == 0)
00879 return it->first;
00880 it++;
00881 }
00882 return NO_ADDRESS;
00883 }
00884
00885 void Win32BinaryFile::AddSymbol(ADDRESS uNative, const char *pName)
00886 {
00887 dlprocptrs[uNative] = pName;
00888 }
00889
00890 bool Win32BinaryFile::DisplayDetails(const char* fileName, FILE* f
00891 )
00892 {
00893 return false;
00894 }
00895
00896 int Win32BinaryFile::win32Read2(short* ps) const {
00897 unsigned char* p = (unsigned char*)ps;
00898
00899 int n = (int)(p[0] + (p[1] << 8));
00900 return n;
00901 }
00902
00903 int Win32BinaryFile::win32Read4(int* pi) const{
00904 short* p = (short*)pi;
00905 int n1 = win32Read2(p);
00906 int n2 = win32Read2(p+1);
00907 int n = (int) (n1 | (n2 << 16));
00908 return n;
00909 }
00910
00911
00912 int Win32BinaryFile::readNative1(ADDRESS nat) {
00913 PSectionInfo si = GetSectionInfoByAddr(nat);
00914 if (si == 0)
00915 return -1;
00916 ADDRESS host = si->uHostAddr - si->uNativeAddr + nat;
00917 return *(char*)host;
00918 }
00919
00920
00921 int Win32BinaryFile::readNative2(ADDRESS nat) {
00922 PSectionInfo si = GetSectionInfoByAddr(nat);
00923 if (si == 0) return 0;
00924 ADDRESS host = si->uHostAddr - si->uNativeAddr + nat;
00925 int n = win32Read2((short*)host);
00926 return n;
00927 }
00928
00929
00930 int Win32BinaryFile::readNative4(ADDRESS nat) {
00931 PSectionInfo si = GetSectionInfoByAddr(nat);
00932 if (si == 0) return 0;
00933 ADDRESS host = si->uHostAddr - si->uNativeAddr + nat;
00934 int n = win32Read4((int*)host);
00935 return n;
00936 }
00937
00938
00939 QWord Win32BinaryFile::readNative8(ADDRESS nat) {
00940 int raw[2];
00941 #ifdef WORDS_BIGENDIAN // This tests the host machine
00942
00943 raw[1] = readNative4(nat);
00944 raw[0] = readNative4(nat+4);
00945 #else
00946
00947 raw[0] = readNative4(nat);
00948 raw[1] = readNative4(nat+4);
00949 #endif
00950 return *(QWord*)raw;
00951 }
00952
00953
00954 float Win32BinaryFile::readNativeFloat4(ADDRESS nat) {
00955 int raw = readNative4(nat);
00956
00957
00958 return *(float*)&raw;
00959 }
00960
00961
00962 double Win32BinaryFile::readNativeFloat8(ADDRESS nat) {
00963 int raw[2];
00964 #ifdef WORDS_BIGENDIAN // This tests the host machine
00965
00966 raw[1] = readNative4(nat);
00967 raw[0] = readNative4(nat+4);
00968 #else
00969
00970 raw[0] = readNative4(nat);
00971 raw[1] = readNative4(nat+4);
00972 #endif
00973
00974 return *(double*)raw;
00975 }
00976
00977 bool Win32BinaryFile::IsDynamicLinkedProcPointer(ADDRESS uNative)
00978 {
00979 if (dlprocptrs.find(uNative) != dlprocptrs.end())
00980 return true;
00981 return false;
00982 }
00983
00984 bool Win32BinaryFile::IsStaticLinkedLibProc(ADDRESS uNative)
00985 {
00986 #if defined(_WIN32) && !defined(__MINGW32__)
00987 HANDLE hProcess = GetCurrentProcess();
00988 dbghelp::IMAGEHLP_LINE64 line;
00989 line.SizeOfStruct = sizeof(line);
00990 line.FileName = NULL;
00991 dbghelp::SymGetLineFromAddr64(hProcess, uNative, 0, &line);
00992 if (haveDebugInfo && line.FileName == NULL || line.FileName && *line.FileName == 'f')
00993 return true;
00994 #endif
00995
00996 if (IsMinGWsAllocStack(uNative) || IsMinGWsFrameInit(uNative) || IsMinGWsFrameEnd(uNative) ||
00997 IsMinGWsCleanupSetup(uNative) || IsMinGWsMalloc(uNative)) {
00998 return true;
00999 }
01000
01001 return false;
01002 }
01003
01004 bool Win32BinaryFile::IsMinGWsAllocStack(ADDRESS uNative)
01005 {
01006 if (mingw_main) {
01007 PSectionInfo si = GetSectionInfoByAddr(uNative);
01008 if (si) {
01009 ADDRESS host = si->uHostAddr - si->uNativeAddr + uNative;
01010 unsigned char pat[] =
01011 { 0x51, 0x89, 0xE1, 0x83, 0xC1, 0x08, 0x3D, 0x00,
01012 0x10, 0x00, 0x00, 0x72, 0x10, 0x81, 0xE9, 0x00,
01013 0x10, 0x00, 0x00, 0x83, 0x09, 0x00, 0x2D, 0x00,
01014 0x10, 0x00, 0x00, 0xEB, 0xE9, 0x29, 0xC1, 0x83,
01015 0x09, 0x00, 0x89, 0xE0, 0x89, 0xCC, 0x8B, 0x08,
01016 0x8B, 0x40, 0x04, 0xFF, 0xE0 };
01017 if (memcmp((void*)host, pat, sizeof(pat)) == 0) {
01018 return true;
01019 }
01020 }
01021 }
01022 return false;
01023 }
01024
01025 bool Win32BinaryFile::IsMinGWsFrameInit(ADDRESS uNative)
01026 {
01027 if (mingw_main) {
01028 PSectionInfo si = GetSectionInfoByAddr(uNative);
01029 if (si) {
01030 ADDRESS host = si->uHostAddr - si->uNativeAddr + uNative;
01031 unsigned char pat1[] =
01032 { 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x18, 0x89, 0x7D,
01033 0xFC, 0x8B, 0x7D, 0x08, 0x89, 0x5D, 0xF4, 0x89,
01034 0x75, 0xF8 };
01035 if (memcmp((void*)host, pat1, sizeof(pat1)) == 0) {
01036 unsigned char pat2[] =
01037 { 0x85, 0xD2, 0x74, 0x24, 0x8B, 0x42, 0x2C, 0x85,
01038 0xC0, 0x78, 0x3D, 0x8B, 0x42, 0x2C, 0x85, 0xC0,
01039 0x75, 0x56, 0x8B, 0x42, 0x28, 0x89, 0x07, 0x89,
01040 0x7A, 0x28, 0x8B, 0x5D, 0xF4, 0x8B, 0x75, 0xF8,
01041 0x8B, 0x7D, 0xFC, 0x89, 0xEC, 0x5D, 0xC3
01042
01043 };
01044 if (memcmp((void*)(host + sizeof(pat1) + 6), pat2, sizeof(pat2)) == 0) {
01045 return true;
01046 }
01047 }
01048 }
01049 }
01050 return false;
01051 }
01052
01053 bool Win32BinaryFile::IsMinGWsFrameEnd(ADDRESS uNative)
01054 {
01055 if (mingw_main) {
01056 PSectionInfo si = GetSectionInfoByAddr(uNative);
01057 if (si) {
01058 ADDRESS host = si->uHostAddr - si->uNativeAddr + uNative;
01059 unsigned char pat1[] =
01060 { 0x55, 0x89, 0xE5, 0x53, 0x83, 0xEC, 0x14, 0x8B, 0x45, 0x08, 0x8B, 0x18 };
01061 if (memcmp((void*)host, pat1, sizeof(pat1)) == 0) {
01062 unsigned char pat2[] =
01063 { 0x85, 0xC0, 0x74, 0x1B, 0x8B, 0x48, 0x2C, 0x85, 0xC9, 0x78, 0x34, 0x8B,
01064 0x50, 0x2C, 0x85, 0xD2, 0x75, 0x4D, 0x89, 0x58, 0x28, 0x8B, 0x5D, 0xFC,
01065 0xC9, 0xC3
01066 };
01067 if (memcmp((void*)(host + sizeof(pat1) + 5), pat2, sizeof(pat2)) == 0) {
01068 return true;
01069 }
01070 }
01071 }
01072 }
01073 return false;
01074 }
01075
01076 bool Win32BinaryFile::IsMinGWsCleanupSetup(ADDRESS uNative)
01077 {
01078 if (mingw_main) {
01079 PSectionInfo si = GetSectionInfoByAddr(uNative);
01080 if (si) {
01081 ADDRESS host = si->uHostAddr - si->uNativeAddr + uNative;
01082 unsigned char pat1[] =
01083 { 0x55, 0x89, 0xE5, 0x53, 0x83, 0xEC, 0x04 };
01084 if (memcmp((void*)host, pat1, sizeof(pat1)) == 0) {
01085 unsigned char pat2[] =
01086 { 0x85, 0xDB, 0x75, 0x35 };
01087 if (memcmp((void*)(host + sizeof(pat1) + 6), pat2, sizeof(pat2)) == 0) {
01088 unsigned char pat3[] =
01089 { 0x83, 0xF8, 0xFF, 0x74, 0x24, 0x85, 0xC0, 0x89, 0xC3, 0x74, 0x0E,
01090 0x8D, 0x74, 0x26, 0x00 };
01091 if (memcmp((void*)(host + sizeof(pat1) + 6 + sizeof(pat2) + 16), pat3, sizeof(pat3)) == 0) {
01092 return true;
01093 }
01094 }
01095 }
01096 }
01097 }
01098 return false;
01099 }
01100
01101 bool Win32BinaryFile::IsMinGWsMalloc(ADDRESS uNative)
01102 {
01103 if (mingw_main) {
01104 PSectionInfo si = GetSectionInfoByAddr(uNative);
01105 if (si) {
01106 ADDRESS host = si->uHostAddr - si->uNativeAddr + uNative;
01107 unsigned char pat1[] =
01108 { 0x55, 0x89, 0xE5, 0x8D, 0x45, 0xF4, 0x83, 0xEC, 0x58, 0x89, 0x45, 0xE0, 0x8D, 0x45, 0xC0, 0x89,
01109 0x04, 0x24, 0x89, 0x5D, 0xF4, 0x89, 0x75, 0xF8, 0x89, 0x7D, 0xFC };
01110 if (memcmp((void*)host, pat1, sizeof(pat1)) == 0) {
01111 unsigned char pat2[] =
01112 { 0x89, 0x65, 0xE8 };
01113 if (memcmp((void*)(host + sizeof(pat1) + 0x15), pat2, sizeof(pat2)) == 0) {
01114 return true;
01115 }
01116 }
01117 }
01118 }
01119 return false;
01120 }
01121
01122 ADDRESS Win32BinaryFile::IsJumpToAnotherAddr(ADDRESS uNative)
01123 {
01124 if ((readNative1(uNative) & 0xff) != 0xe9)
01125 return NO_ADDRESS;
01126 return readNative4(uNative+1) + uNative + 5;
01127 }
01128
01129 const char *Win32BinaryFile::GetDynamicProcName(ADDRESS uNative)
01130 {
01131 return dlprocptrs[uNative].c_str();
01132 }
01133
01134 LOAD_FMT Win32BinaryFile::GetFormat() const
01135 {
01136 return LOADFMT_PE;
01137 }
01138
01139 MACHINE Win32BinaryFile::GetMachine() const
01140 {
01141 return MACHINE_PENTIUM;
01142 }
01143
01144 bool Win32BinaryFile::isLibrary() const
01145 {
01146 return ( (m_pPEHeader->Flags & 0x2000) != 0 );
01147 }
01148
01149 ADDRESS Win32BinaryFile::getImageBase()
01150 {
01151 return m_pPEHeader->Imagebase;
01152 }
01153
01154 size_t Win32BinaryFile::getImageSize()
01155 {
01156 return m_pPEHeader->ImageSize;
01157 }
01158
01159 std::list<const char *> Win32BinaryFile::getDependencyList()
01160 {
01161 return std::list<const char *>();
01162 }
01163
01164 DWord Win32BinaryFile::getDelta() {
01165
01166
01167
01168 return (DWord)base - (DWord)m_pPEHeader->Imagebase;
01169 }
01170
01171
01172
01173
01174 extern "C" {
01175 #ifdef _WIN32
01176 __declspec(dllexport)
01177 #endif
01178 BinaryFile* construct()
01179 {
01180 return new Win32BinaryFile;
01181 }
01182 }
01183
01184 void Win32BinaryFile::dumpSymbols() {
01185 std::map<ADDRESS, std::string>::iterator it;
01186 std::cerr << std::hex;
01187 for (it = dlprocptrs.begin(); it != dlprocptrs.end(); ++it)
01188 std::cerr << "0x" << it->first << " " << it->second << " ";
01189 std::cerr << std::dec << "\n";
01190 }
01191