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
00029
00030
00031 #include <algorithm>
00032 #include "../common/h/parseauxv.h"
00033 #include "Object.h"
00034 #include "Object-nt.h"
00035 #include "emitWin.h"
00036 #include "Symtab.h"
00037 #include <iostream>
00038 #include <dbghelp.h>
00039
00040
00041 using namespace Dyninst;
00042 using namespace Dyninst::SymtabAPI;
00043 using namespace std;
00044
00045
00046 emitWin::emitWin(PCHAR baseaddress, Object *o_nt, void (*err_func)(const char *)){
00047 base_addr = baseaddress;
00048 obj_nt = o_nt;
00049 err_func_ = err_func;
00050 }
00051
00052 PIMAGE_SECTION_HEADER emitWin::CreateSecHeader(unsigned int size, PIMAGE_SECTION_HEADER preSecHdr){
00053 DWORD mem_offset, mem_size, disk_offset, disk_size;
00054 PIMAGE_NT_HEADERS pNTHeader = obj_nt -> GetImageHeader();
00055
00056 disk_size=PEAlign(size,pNTHeader -> OptionalHeader.FileAlignment);
00057 mem_size=PEAlign(disk_size, pNTHeader->OptionalHeader.SectionAlignment);
00058
00059 disk_offset=PEAlign(preSecHdr->PointerToRawData+preSecHdr->SizeOfRawData,
00060 pNTHeader->OptionalHeader.FileAlignment);
00061
00062 mem_offset=PEAlign(preSecHdr->VirtualAddress+preSecHdr->Misc.VirtualSize,
00063 pNTHeader->OptionalHeader.SectionAlignment);
00064 PIMAGE_SECTION_HEADER newSecHdr=new IMAGE_SECTION_HEADER;
00065 memset(newSecHdr,0,(size_t)sizeof(IMAGE_SECTION_HEADER));
00066
00067 newSecHdr->PointerToRawData=disk_offset;
00068 newSecHdr->VirtualAddress=mem_offset;
00069
00070 newSecHdr->SizeOfRawData=disk_size;
00071 newSecHdr->Misc.VirtualSize=mem_size;
00072 newSecHdr->Characteristics=0xC0000040;
00073 return newSecHdr;
00074 }
00075
00076 bool emitWin::AlignSection(PIMAGE_SECTION_HEADER p){
00077 return true;
00078 }
00079
00080
00081 static Region *getDyninstSection(Symtab *st)
00082 {
00083 vector<Region*> regs;
00084 st->getAllRegions(regs);
00085 return regs.back();
00086 }
00087
00088 static Offset copy_ILT_or_ALT(unsigned int idtIdx,
00089 vector<pair<string,IMAGE_IMPORT_DESCRIPTOR> > &idt,
00090 const vector<void*> &iltEntries,
00091 const unsigned char *ptrDyn,
00092 Offset secOff,
00093 Offset ptrToWrite,
00094 int addrWidth,
00095 bool isILT)
00096 {
00097 assert(idtIdx < idt.size());
00098 if (isILT) {
00099 idt[idtIdx].second.OriginalFirstThunk = secOff + ptrToWrite;
00100 } else {
00101 idt[idtIdx].second.FirstThunk = secOff + ptrToWrite;;
00102 }
00103 idtIdx++;
00104
00105 for (vector<void*>::const_iterator eit = iltEntries.begin();
00106 eit != iltEntries.end();
00107 eit++)
00108 {
00109 if (0 == (*eit) && idtIdx < idt.size()) {
00110 if (isILT) {
00111 idt[idtIdx].second.OriginalFirstThunk = secOff + ptrToWrite + addrWidth;
00112 } else {
00113 idt[idtIdx].second.FirstThunk = secOff + ptrToWrite + addrWidth;
00114 }
00115 idtIdx++;
00116 }
00117 memcpy((void*)(ptrDyn + ptrToWrite), &(*eit), addrWidth);
00118 ptrToWrite += addrWidth;
00119 }
00120 return ptrToWrite;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 bool emitWin::writeImpTable(Symtab* obj)
00138 {
00139 bool ret = true;
00140
00141
00142 vector<pair<string,IMAGE_IMPORT_DESCRIPTOR> > & idt = obj_nt->getImportDescriptorTable();
00143 int origIDTSize = idt.size();
00144
00145
00146 Region *dynSec = getDyninstSection(obj);
00147 assert(dynSec);
00148
00149 std::map<string, map<Offset, string> > & ref = obj_nt->getRefs();
00150
00151
00152
00153 map<string, map<string, WORD> > hnt;
00154 for(map<string, map<Offset, string> >::iterator lit=ref.begin();
00155 lit != ref.end();
00156 lit++)
00157 {
00158
00159 IMAGE_IMPORT_DESCRIPTOR newID;
00160 newID.FirstThunk = NULL;
00161 newID.ForwarderChain=0;
00162 newID.Name = NULL;
00163 newID.OriginalFirstThunk=NULL;
00164 newID.TimeDateStamp=0;
00165 idt.push_back(std::pair<string, IMAGE_IMPORT_DESCRIPTOR>(lit->first, newID));
00166
00167 hnt[lit->first];
00168 map<string, map<string, WORD> >::iterator libHNT = hnt.find(lit->first);
00169
00170
00171 for(map<Offset, string>::iterator fit = lit->second.begin();
00172 fit != lit->second.end();
00173 fit++)
00174 {
00175 if (libHNT->second.end() == libHNT->second.find(fit->second)) {
00176
00177 (libHNT->second)[fit->second] = 0;
00178 }
00179 }
00180 }
00181
00182
00183 unsigned int numImports = 0;
00184
00185 unsigned int hntSize = 0;
00186 unsigned int libNameSize = 0;
00187 for (map<string, map<string, WORD> >::iterator hit = hnt.begin();
00188 hit != hnt.end();
00189 hit++)
00190 {
00191 numImports += hit->second.size();
00192 libNameSize += hit->first.size() + 1;
00193 for (map<string, WORD>::iterator fit = hit->second.begin();
00194 fit != hit->second.end();
00195 fit++)
00196 {
00197 int nameLen = fit->first.size();
00198 hntSize += 2 + nameLen + 1 + ((nameLen+1) % 2);
00199 }
00200 }
00201 unsigned int idtSize = sizeof(IMAGE_IMPORT_DESCRIPTOR) * (idt.size() + 1);
00202 unsigned int iltSize = (numImports + hnt.size()) * obj->getAddressWidth();
00203 unsigned int iatSize = iltSize;
00204 unsigned int secSize = dynSec->getDiskSize() + idtSize + iltSize + hntSize + iatSize + libNameSize;
00205 unsigned char* ptrDyn = (unsigned char*) GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, secSize);
00206
00207
00208 Offset ptrToWrite = 0;
00209
00210
00211 memcpy(ptrDyn + ptrToWrite,
00212 dynSec->getPtrToRawData(),
00213 dynSec->getDiskSize());
00214 ptrToWrite += dynSec->getDiskSize();
00215 dynSec->setPtrToRawData(ptrDyn, secSize);
00216
00217
00218 assert(sizeof(void*) == obj->getAddressWidth());
00219 vector<void*> iltEntries;
00220 for (map<string, map<string, WORD> >::iterator hit = hnt.begin();
00221 hit != hnt.end();
00222 hit++)
00223 {
00224 for (map<string, WORD>::iterator fit = hit->second.begin();
00225 fit != hit->second.end();
00226 fit++)
00227 {
00228
00229 iltEntries.push_back((void*)(dynSec->getMemOffset() + ptrToWrite));
00230
00231
00232 memcpy(ptrDyn + ptrToWrite,
00233 &(fit->second),
00234 2);
00235 ptrToWrite += 2;
00236
00237
00238 int nameLen = fit->first.size() + 1;
00239 memcpy(ptrDyn + ptrToWrite,
00240 fit->first.c_str(),
00241 nameLen);
00242 ptrToWrite += nameLen;
00243
00244
00245 int padLen = nameLen % 2;
00246 if (padLen) {
00247 ptrDyn[ptrToWrite] = '\0';
00248 ptrToWrite += padLen;
00249 }
00250 }
00251
00252
00253 iltEntries.push_back(0);
00254 }
00255
00256
00257 ptrToWrite = copy_ILT_or_ALT(origIDTSize,
00258 idt,
00259 iltEntries,
00260 ptrDyn,
00261 dynSec->getMemOffset(),
00262 ptrToWrite,
00263 obj->getAddressWidth(),
00264 true);
00265
00266
00267 Offset iatOffset = dynSec->getMemOffset() + ptrToWrite;
00268 ptrToWrite = copy_ILT_or_ALT(origIDTSize,
00269 idt,
00270 iltEntries,
00271 ptrDyn,
00272 dynSec->getMemOffset(),
00273 ptrToWrite,
00274 obj->getAddressWidth(),
00275 false);
00276 assert(iatSize == (dynSec->getMemOffset() + ptrToWrite - iatOffset));
00277
00278
00279 for (int idtIdx = origIDTSize; idtIdx != idt.size(); idtIdx++) {
00280 idt[idtIdx].second.Name = dynSec->getMemOffset() + ptrToWrite;
00281 int nameLen = idt[idtIdx].first.size() + 1;
00282 memcpy(ptrDyn + ptrToWrite,
00283 idt[idtIdx].first.c_str(),
00284 nameLen);
00285 ptrToWrite += nameLen;
00286 }
00287
00288
00289 Offset idtOffset = dynSec->getMemOffset() + ptrToWrite;
00290 for (vector<pair<string,IMAGE_IMPORT_DESCRIPTOR> >::iterator dit = idt.begin();
00291 dit != idt.end();
00292 dit++)
00293 {
00294 memcpy(ptrDyn + ptrToWrite,
00295 (void*)& dit->second,
00296 sizeof(IMAGE_IMPORT_DESCRIPTOR));
00297 ptrToWrite += sizeof(IMAGE_IMPORT_DESCRIPTOR);
00298 }
00299 memset(ptrDyn + ptrToWrite, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR));
00300 ptrToWrite += sizeof(IMAGE_IMPORT_DESCRIPTOR);
00301 assert(idtSize == (dynSec->getMemOffset() + ptrToWrite - idtOffset));
00302
00303 assert(ptrToWrite == secSize);
00304
00305
00306 if (obj_nt->getPEHdr()->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT) {
00307 obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = idtOffset;
00308 obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = idtSize;
00309 } else {
00310 ret = false;
00311 }
00312
00313 return ret;
00314 }
00315
00316
00317 bool emitWin::driver(Symtab *obj, std::string fName){
00318
00319 if(!obj_nt->getRefs().empty())
00320 writeImpTable(obj);
00321
00322 Offset MoveAheadOffset=0;
00323
00324 std::vector<Region *> newregs;
00325 if(!obj -> getAllNewRegions(newregs)){
00326 log_winerror(err_func_, "No new section added, no need to drive");
00327 printf("No new section added, no need to drive\n");
00328 return false;
00329 }
00330
00331
00332 unsigned int n1 = NumOfAllowedSecInSectionTable();
00333
00334 if(newregs.size() > n1){
00335
00336
00337 unsigned int n2= NumOfAllowedSecInDosHeader();
00338 if(newregs.size() > n1+n2){
00339
00340 log_winerror(err_func_, "no way to insert all new added sections, abort.\n");
00341 printf("no way to insert all new added sections, abort.\n");
00342 return false;
00343 }
00344
00345 isMoveAhead = true;
00346
00347 MoveAheadOffset = SizeOfSecHeader*(newregs.size() - n1);
00348
00349
00350 }
00351
00352
00353 else
00354 isMoveAhead = false;
00355
00356
00357 std::vector<Region *> regs;
00358 if(!(obj -> getAllRegions(regs))) {
00359 printf("Failed to get regions.\n");
00360 log_winerror(err_func_, "Failed to get regions.\n");
00361 return false;
00362 }
00363
00364 IMAGE_DOS_HEADER DosHeader;
00365 memcpy(&DosHeader, base_addr, sizeof(IMAGE_DOS_HEADER));
00366 DWORD peHdrOffset = DosHeader.e_lfanew;
00367 DWORD dwDosStufOffset = sizeof(IMAGE_DOS_HEADER);
00368 PIMAGE_NT_HEADERS NTHeader=new IMAGE_NT_HEADERS;
00369
00370 memcpy(NTHeader, base_addr + DosHeader.e_lfanew, sizeof(IMAGE_NT_HEADERS));
00371 assert(NTHeader->Signature == IMAGE_NT_SIGNATURE);
00372
00373
00374
00375 std::vector<PIMAGE_SECTION_HEADER> secHdrs;
00376 PIMAGE_NT_HEADERS pehdr = obj_nt->GetImageHeader();
00377
00378
00379 PIMAGE_SECTION_HEADER pScnHdr = (PIMAGE_SECTION_HEADER)(((char*)pehdr) +
00380 sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) +
00381 pehdr->FileHeader.SizeOfOptionalHeader);
00382
00383
00384 for(unsigned int i=0; i<NTHeader->FileHeader.NumberOfSections; i++){
00385 PIMAGE_SECTION_HEADER p=new IMAGE_SECTION_HEADER;
00386 memcpy(p,pScnHdr, sizeof(IMAGE_SECTION_HEADER));
00387
00388 secHdrs.push_back(p);
00389
00390 pScnHdr++;
00391 }
00392
00393 PIMAGE_SECTION_HEADER pre = secHdrs[secHdrs.size()-1];
00394 for(unsigned int i=0; i<newregs.size(); i++){
00395 PIMAGE_SECTION_HEADER p = CreateSecHeader(newregs[i]->getDiskSize(), pre);
00396 if((size_t)strlen(newregs[i]->getRegionName().c_str())> 8)
00397 memcpy(p->Name, newregs[i]->getRegionName().c_str(),8);
00398 else
00399 memcpy(p->Name, newregs[i]->getRegionName().c_str(),
00400 (size_t)strlen(newregs[i]->getRegionName().c_str()));
00401 secHdrs.push_back(p);
00402 pre = p;
00403 }
00404
00405
00406 for(unsigned int i=0; i<secHdrs.size(); i++){
00407 printf("%s, diskOff=%x, diskSize=%x, memoff=%x, memsize=%x\n",
00408 (const char*)secHdrs[i]->Name,secHdrs[i]->PointerToRawData,
00409 secHdrs[i]->SizeOfRawData, secHdrs[i]->VirtualAddress,
00410 secHdrs[i]->Misc.VirtualSize);
00411 }
00412
00413
00414 PIMAGE_SECTION_HEADER lastSec = secHdrs[secHdrs.size()-1];
00415 const int REWRITE_LABEL_SIZE = obj->getAddressWidth() + 16;
00416 if (obj->getObject()->trapHeader()) {
00417 lastSec->SizeOfRawData = PEAlign(
00418 lastSec->SizeOfRawData + REWRITE_LABEL_SIZE,
00419 pehdr->OptionalHeader.FileAlignment);
00420 lastSec->Misc.VirtualSize = PEAlign(
00421 lastSec->SizeOfRawData + REWRITE_LABEL_SIZE,
00422 pehdr->OptionalHeader.SectionAlignment);
00423 }
00424
00425
00426 DWORD dwFileSize = lastSec->PointerToRawData + lastSec->SizeOfRawData;
00427
00428
00429
00430 HANDLE hFile = CreateFileA(fName.c_str(),GENERIC_WRITE,
00431 FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
00432 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00433
00434 if(hFile == INVALID_HANDLE_VALUE){
00435 log_winerror(err_func_, "Failed to open a file to write.\n");
00436 printf("Failed to open a file to write.\n");
00437 return false;
00438 }
00439
00440 PCHAR pMem = (char*)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,dwFileSize);
00441 if(pMem == NULL){
00442 log_winerror(err_func_, "Failed to allocate memory space for written file\n");
00443 printf("Failed to allocate memory space for written file\n");
00444 return false;
00445 }
00446
00447
00448 Offset writeOffset = 0;
00449
00450 memcpy(pMem,&DosHeader,sizeof(IMAGE_DOS_HEADER));
00451 writeOffset += sizeof(IMAGE_DOS_HEADER);
00452
00453
00454 if(isMoveAhead)
00455 ((PIMAGE_DOS_HEADER)pMem)->e_lfanew -= MoveAheadOffset;
00456
00457
00458 PCHAR dosStub = base_addr + sizeof(IMAGE_DOS_HEADER);
00459 if(isMoveAhead){
00460 memcpy(pMem+writeOffset, dosStub, peHdrOffset-sizeof(IMAGE_DOS_HEADER)-MoveAheadOffset);
00461 writeOffset+=peHdrOffset-sizeof(IMAGE_DOS_HEADER)-MoveAheadOffset;
00462 }
00463 else{
00464 memcpy(pMem+writeOffset, dosStub, peHdrOffset-sizeof(IMAGE_DOS_HEADER));
00465 writeOffset += peHdrOffset-sizeof(IMAGE_DOS_HEADER);
00466 }
00467
00468
00469
00470
00471 NTHeader->FileHeader.NumberOfSections = regs.size();
00472
00473 NTHeader->OptionalHeader.SizeOfImage = secHdrs[secHdrs.size()-1]->VirtualAddress +
00474 secHdrs[secHdrs.size()-1]->Misc.VirtualSize;
00475
00476
00477 if(!obj_nt->getRefs().empty() && NTHeader->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT) {
00478 Offset newOff = obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
00479 Offset newSize = obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
00480 NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = newOff;
00481 NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = newSize;
00482 printf("new import descriptor table address: %lu size: %lu\n", newOff, newSize);
00483 }
00484
00485 if(!obj_nt->getRefs().empty() && NTHeader->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IAT) {
00486 Offset newOff = obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
00487 Offset newSize = obj_nt->getPEHdr()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
00488 NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = newOff;
00489 NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = newSize;
00490 printf("new import address table address: %lu size: %lu\n", newOff, newSize);
00491 }
00492
00493 memcpy(pMem+writeOffset, NTHeader,sizeof(IMAGE_NT_HEADERS));
00494
00495 if(bit_addr != 0){
00496 assert(NTHeader->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT);
00497 PIMAGE_NT_HEADERS newpeHdr = (PIMAGE_NT_HEADERS)((void *)(pMem+writeOffset));
00498 PIMAGE_OPTIONAL_HEADER newoptHdr = (PIMAGE_OPTIONAL_HEADER)&newpeHdr -> OptionalHeader;
00499 printf("old address: 0x%x\n", newoptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress);
00500 newoptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress+=sizeof(IMAGE_SECTION_HEADER);
00501 printf("new address: 0x%x\n", newoptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress);
00502 }
00503 writeOffset += sizeof(IMAGE_NT_HEADERS);
00504
00505
00506
00507 DWORD dwFirstSectionHeaderOffset = writeOffset;
00508 unsigned int numSecns = secHdrs.size();
00509 for(unsigned int i=0; i<numSecns; i++){
00510 memcpy(pMem+dwFirstSectionHeaderOffset + i*sizeof(IMAGE_SECTION_HEADER),secHdrs[i],
00511 sizeof(IMAGE_SECTION_HEADER));
00512 memcpy(pMem+secHdrs[i]->PointerToRawData, regs[i]->getPtrToRawData(),regs[i]->getDiskSize());
00513 }
00514
00515
00516 Address trapHead = obj->getObject()->trapHeader();
00517 Address writeTarg = (Address) (pMem
00518 + lastSec->PointerToRawData
00519 + lastSec->SizeOfRawData
00520 - REWRITE_LABEL_SIZE);
00521 memcpy((void*)writeTarg, (void*) &trapHead, obj->getAddressWidth());
00522 memcpy((void*)(writeTarg + obj->getAddressWidth()), "DYNINST_REWRITE", 16);
00523
00524
00525 if(bit_addr != 0){
00526 memcpy(pMem+dwFirstSectionHeaderOffset + secHdrs.size()*sizeof(IMAGE_SECTION_HEADER),
00527 (char*)(base_addr+bit_addr), bit_size);
00528 }
00529
00530
00531 DWORD dwByteWritten =0;
00532 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
00533 WriteFile(hFile, pMem, dwFileSize,&dwByteWritten, NULL);
00534
00535 SetFilePointer(hFile,dwFileSize,NULL,FILE_BEGIN);
00536 SetEndOfFile(hFile);
00537 CloseHandle(hFile);
00538
00539 GlobalFree(pMem);
00540
00541 return true;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551 Offset emitWin::PEAlign(Offset dwAddr,Offset dwAlign)
00552 {
00553 return(((dwAddr + dwAlign - 1) / dwAlign) * dwAlign);
00554 }
00555
00556
00557
00558 unsigned int emitWin::NumOfTotalAllowedSec(){
00559 unsigned int unusedSpaces = 0;
00560
00561
00562 PIMAGE_NT_HEADERS peHdrs = obj_nt -> GetImageHeader();
00563
00564 if(peHdrs){
00565
00566 }
00567
00568 return unusedSpaces;
00569 }
00570
00571
00572
00573 unsigned int emitWin::NumOfAllowedSecInSectionTable(){
00574
00575
00576 PIMAGE_NT_HEADERS peHdr = obj_nt -> GetImageHeader();
00577 IMAGE_OPTIONAL_HEADER optHdr = peHdr -> OptionalHeader;
00578
00579 unsigned int NumOfDataDir = optHdr.NumberOfRvaAndSizes;
00580
00581 assert( NumOfDataDir == 16);
00582
00583
00584
00585
00586 IMAGE_DATA_DIRECTORY bit = optHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
00587 bit_addr = bit.VirtualAddress;
00588 bit_size = bit.Size;
00589
00590
00591
00592
00593 PIMAGE_SECTION_HEADER pScnHdr = (PIMAGE_SECTION_HEADER)(((char*)peHdr) +
00594 sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) +
00595 peHdr->FileHeader.SizeOfOptionalHeader);
00596 unsigned int nSections = peHdr->FileHeader.NumberOfSections;
00597
00598 DWORD dwFirstSectionHeaderOffset = ((PIMAGE_DOS_HEADER)base_addr)->e_lfanew + sizeof(IMAGE_NT_HEADERS);
00599
00600 DWORD dwStuffSize = pScnHdr ->PointerToRawData - (dwFirstSectionHeaderOffset + nSections*sizeof(IMAGE_SECTION_HEADER));
00601
00602 unsigned int ret = (dwStuffSize - bit_size)/SizeOfSecHeader;
00603
00604 return ret;
00605
00606 }
00607
00608
00609
00610 unsigned int emitWin::NumOfAllowedSecInDosHeader(){
00611
00612 PIMAGE_NT_HEADERS peHdr = obj_nt -> GetImageHeader();
00613
00614 unsigned int size = (char*)peHdr - (base_addr+sizeof(IMAGE_DOS_HEADER));
00615 unsigned int ret = size/SizeOfSecHeader;
00616
00617 return ret;
00618 }
00619
00620 void emitWin::log_winerror(void (*err_func)(const char *), const char* msg) {
00621 err_func(msg);
00622 }