Xiao.Zhu C++
Xiao.Zhu C++
C++博客
::
首页
::
新随笔
::
联系
::
聚合
::
管理
::
29 随笔 :: 14 文章 :: 17 评论 :: 0 Trackbacks
<
2012年11月
>
日
一
二
三
四
五
六
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
(2)
RTP(2)
(rss)
随笔档案
(29)
2008年11月 (1)
2007年9月 (1)
2007年8月 (4)
2007年7月 (1)
2007年6月 (2)
2007年5月 (10)
2007年4月 (8)
2007年3月 (2)
文章分类
(13)
ACE(1)
(rss)
C/C++(11)
(rss)
NetWork(1)
(rss)
文章档案
(14)
2007年5月 (1)
2007年3月 (13)
收藏夹
(1)
收藏(1)
(rss)
外挂
499
CodeGuru
CodeProject
Torque游戏引擎研究与开发
Torque游戏引擎研究与开发
VC知识库
北冥工作室
读书人编程文档中心
开源社区
设计模式
外挂
外挂
游戏外挂研究院
搜索
最新随笔
1. 嵌入式程序员应该知道的16个问题
2. Visual Studio 6.0 和 Visual Studio 2005 编辑器配色方案
3. 杂7杂8技术资料
4. linux下基于jrtplib库的实时传送实现
5. RTP
6. 将进程变成一个线程执行代码
7. 中国职员的九种劣根性
8. 深圳
9. 串口
10. Windows Sockets 2.0:使用完成端口高性能,可扩展性Winsock服务程序 (转)
最新评论
1. re: 将进程变成一个线程执行代码
将进程变成线程有何实际意义,进程是线程的容器,真正干活的都是线程,只是线程不享受独立的内存单元,难道就是为了利用多线程共享内存来节省下这点空间。
--小yun哥
2. re: 中国职员的九种劣根性
把职员的9种劣性+老板的9种劣性和起来.
就是中国的企业文化
貌似攻击别人了....
--一个无名的坏人
3. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
4. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
5. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
6. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
7. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
8. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
9. re: 中国职员的九种劣根性
评论内容较长,点击标题查看
--a member
10. re: 中国职员的九种劣根性
本文作者看问题、分析问题至多看到自己脚尖前几寸的地方,还到处说教。更甚者扯张硕大的虎皮--中国职员的九种劣根性--来说事儿。自个儿先修身养性再扯这张虎皮吧!
--孟斐
评论排行榜
1. 中国职员的九种劣根性(10)
2. Visual Studio 6.0 和 Visual Studio 2005 编辑器配色方案(4)
3. 将进程变成一个线程执行代码(1)
4. RTP(1)
5. 上班人员必读:“五险一金”详解!(1)
6. 感 情(0)
7. HeapAlloc和GlobalAlloc以及VirtualAlloc三者之间的关系(转贴)- -(0)
8. 多人在线游戏开发心得(服务器端)(转贴)(0)
9. 游戏外挂技术初探~ (0)
10. 协议型网络游戏外挂制作之外挂窗口 (0)
将进程变成一个线程执行代码
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
43
struct 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
55
struct 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
122
struct 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
136
struct 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
157
struct 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
173
bool 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
250
int
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
291
unsigned
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
311
bool 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
373
struct 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
387
void
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
431
typedef 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
446
BOOL 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
482
BOOL hasRelocationTable(PE_ExtHeader
*
inpeXH)
483
{
484
if
(inpeXH
->
relocationTableAddress
&&
inpeXH
->
relocationTableSize)
485
{
486
return
TRUE;
487
}
488
return
FALSE;
489
}
490
491
492
typedef 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
515
void
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
(
!
v
&&
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
636
int
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哥
将进程变成线程有何实际意义,进程是线程的容器,真正干活的都是线程,只是线程不享受独立的内存单元,难道就是为了利用多线程共享内存来节省下这点空间。
回复
更多评论
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
博问
Chat2DB
管理
Powered by:
C++博客
Copyright © Xiao.Zhu