三、代码实现(DELPHI版本),采用第三种方式实现代码插入。

1. 定义两个类,一个用来实现在内存中建立输入表;一个用来实现对PE头的代码插入。

DelphiCode:

  1. const MAX_SECTION_NUM = 20;
  2. const DYN_LOADER_START_MAGIC = $C0DE51A9;
  3. const DYN_LOADER_END_MAGIC = $C0DEE2DE;
  4. const DYN_LOADER_START_DATA1 = $DA1EDA1E;
  5.  
  6. const IMPORT_TABLE_EXE = 0;
  7. const IMPORT_TABLE_DLL = 1;
  8.  
  9. Type
  10. TIIDUnion = record
  11. case Integer of
  12. 0: (Characteristics: DWORD); // 0 for terminating null import descriptor
  13. 1: (OriginalFirstThunk: DWORD); // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
  14. end;
  15.  
  16. PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
  17. {$EXTERNALSYM PIMAGE_IMPORT_DESCRIPTOR}
  18. _IMAGE_IMPORT_DESCRIPTOR = record
  19. Union: TIIDUnion;
  20. TimeDateStamp: DWORD;
  21. ForwarderChain: DWORD;
  22. Name: DWORD;
  23. FirstThunk: DWORD;
  24. end;
  25. {$EXTERNALSYM _IMAGE_IMPORT_DESCRIPTOR}
  26. IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
  27. {$EXTERNALSYM IMAGE_IMPORT_DESCRIPTOR}
  28. TImageImportDecriptor = IMAGE_IMPORT_DESCRIPTOR;
  29. PImageImportDecriptor = PIMAGE_IMPORT_DESCRIPTOR;
  30.  
  31. PIMAGE_TLS_DIRECTORY32 = ^IMAGE_TLS_DIRECTORY32;
  32. {$EXTERNALSYM PIMAGE_TLS_DIRECTORY32}
  33. _IMAGE_TLS_DIRECTORY32 = record
  34. StartAddressOfRawData: DWORD;
  35. EndAddressOfRawData: DWORD;
  36. AddressOfIndex: DWORD;
  37. AddressOfCallBacks: DWORD;
  38. SizeOfZeroFill: DWORD;
  39. Characteristics: DWORD;
  40. end;
  41. {$EXTERNALSYM _IMAGE_TLS_DIRECTORY32}
  42. IMAGE_TLS_DIRECTORY32 = _IMAGE_TLS_DIRECTORY32;
  43. {$EXTERNALSYM IMAGE_TLS_DIRECTORY32}
  44. TImageTlsDirectory32 = IMAGE_TLS_DIRECTORY32;
  45. PImageTlsDirectory32 = PIMAGE_TLS_DIRECTORY32;
  46.  
  47. PImageImport = ^TImageImport;
  48. TImageImport = packed record
  49. szLibrary : array[0..31] of char;
  50. ThunksList : TList;
  51. end;
  52.  
  53. {在内存中建立一个输入表的内存块,地址放在pMem中,大小是dwSize}
  54. TImportTableMaker = class
  55. private
  56. function GetIATSize : DWORD;
  57. procedure Init(iType : integer);
  58. protected
  59. ImportTable : TList;
  60. public
  61. dwSize : DWORD;
  62. pMem : Pointer;
  63. constructor Create(iType : integer);
  64. destructor Destroy; override;
  65. procedure Build(baseRVA : DWORD);
  66. end;
  67.  
  68. {用来传递数据的一个结构}
  69.  
  70. PData = ^TData;
  71. TData = record
  72. dwReserved1 : DWORD;
  73. dwFileType : DWORD;
  74. dwImageBase : DWORD;
  75. dwOrgEntryPoint : DWORD;
  76. dwImportVAddr : DWORD;
  77. dwRelocationVAddr : DWORD;
  78. dwRelocationSize : DWORD;
  79. imgTLSDirectory : IMAGE_TLS_DIRECTORY32;
  80. end;
  81.  
  82. TPE = class
  83. private
  84. dwFileSize : DWORD;
  85. pMem : Pointer;
  86. SectionNum : integer;
  87. pNewSection : Pointer;
  88. function ReturnToBytePtr(FuncCode : pointer; findstr : DWORD): pointer;
  89. procedure SetSectionsWritePermission;
  90. procedure CopyData(dwVirtualAddress : DWORD);
  91. protected
  92. ITMaker : TImportTableMaker;
  93.  
  94. imgDosHeader : TImageDosHeader;
  95. pDosStub : Pointer;
  96. dwDosStubSize : DWORD;
  97. dwDosStubOffset : DWORD;
  98. imgNtHeaders : TImageNtHeaders;
  99. imgSectionHeaders : array[0..MAX_SECTION_NUM -1] of TImageSectionHeader;
  100. imgSections : array[0..MAX_SECTION_NUM -1] of Pointer;
  101. imgTLSDirectory : IMAGE_TLS_DIRECTORY32;
  102. function PEAlign(dwTarNum : DWORD; dwAlignTo : DWORD) : DWORD;
  103. procedure AlignmentSections;
  104. function Offset2RVA(dwOffset : DWORD) : DWORD;
  105. function RVA2Offset(dwRVA : DWORD) : DWORD;
  106. function ImgRVA2Section(dwRVA : DWORD) : PImageSectionHeader;
  107. function ImgOffset2Section(dwOffset: DWORD): PImageSectionHeader;
  108. function ImgOffset2SectionNum(dwOffset: DWORD): integer;
  109. function AddNewSection(szName: string; dwSize: DWORD): PImageSectionHeader;
  110. public
  111. constructor Create;
  112. destructor Destroy; override;
  113. procedure OpenFile(filename : string);
  114. procedure SaveFile(filename : string);
  115. procedure CyrptFile;
  116. end;

二、类代码

DelphiCode:

  1. implementation
  2.  
  3. uses PEInit; //被用来插入的代码单元
  4.  
  5. const szWindowsAPIs : array[0..10] of string = ('Kernel32.dll',
  6. 'GetModuleHandleA',
  7. 'VirtualProtect',
  8. 'GetModuleFileNameA',
  9. 'CreateFileA',
  10. 'GlobalAlloc',
  11. '',
  12. 'User32.dll',
  13. 'MessageBoxA',
  14. '',
  15. '');
  16. const szIATEXEStrings : array[0..4] of string = ('Kernel32.dll',
  17. 'LoadLibraryA',
  18. 'GetProcAddress',
  19. '',
  20. '');
  21.  
  22. const szIATDLLStrings : array[0..29] of string = (
  23. 'Kernel32.dll',
  24. 'LoadLibraryA',
  25. 'GetProcAddress',
  26. 'GetModuleHandleA',
  27. '',
  28. 'User32.dll',
  29. 'GetKeyboardType',
  30. 'WindowFromPoint',
  31. '',
  32. 'AdvApi32.dll',
  33. 'RegQueryValueExA',
  34. 'RegSetValueExA',
  35. 'StartServiceA',
  36. '',
  37. 'Oleaut32.dll',
  38. 'SysFreeString',
  39. 'CreateErrorInfo',
  40. 'SafeArrayPtrOfIndex',
  41. '',
  42. 'Gdi32.dll',
  43. 'UnrealizeObject',
  44. '',
  45. 'Ole32.dll',
  46. 'CreateStreamOnHGlobal',
  47. 'IsEqualGUID',
  48. '',
  49. 'ComCtl32.dll',
  50. 'ImageList_SetIconSize',
  51. '',
  52. '');
  53.  
  54. constructor TPE.Create;
  55. begin
  56. dwDosStubSize := 0;
  57. end;
  58.  
  59. destructor TPE.Destroy;
  60. begin
  61.  
  62. end;
  63.  
  64. {实现FileSection对齐}
  65. function TPE.PEAlign(dwTarNum: DWORD; dwAlignTo: DWORD): DWORD;
  66. begin
  67. result := ((dwTarNum + dwAlignTo - 1) div dwAlignTo) * dwAlignTo;
  68. end;
  69.  
  70. {把所有的节进行Section对齐}
  71. procedure TPE.AlignmentSections;
  72. var
  73. i : integer;
  74. begin
  75. for i:= 0 to imgNtHeaders.FileHeader.NumberOfSections - 1 do
  76. begin
  77. imgSectionHeaders[i].VirtualAddress := PEAlign(imgSectionHeaders[i].VirtualAddress, imgNtHeaders.OptionalHeader.SectionAlignment);
  78. imgSectionHeaders[i].Misc.VirtualSize := PEAlign(imgSectionHeaders[i].Misc.VirtualSize, imgNtHeaders.OptionalHeader.SectionAlignment);
  79. imgSectionHeaders[i].PointerToRawData := PEAlign(imgSectionHeaders[i].PointerToRawData, imgNtHeaders.OptionalHeader.FileAlignment);
  80. imgSectionHeaders[i].SizeOfRawData := PEAlign(imgSectionHeaders[i].SizeOfRawData, imgNtHeaders.OptionalHeader.FileAlignment);
  81. end;
  82. imgNtHeaders.OptionalHeader.SizeOfImage := imgSectionHeaders[i-1].VirtualAddress + imgSectionHeaders[i-1].Misc.VirtualSize;
  83. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress := 0;
  84. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size := 0;
  85. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress := 0;
  86. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size := 0;
  87. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress := 0;
  88. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size := 0;
  89. end;
  90.  
  91. {找到内存中某一个RVA所映射的磁盘文件上的offset}
  92. function TPE.RVA2Offset(dwRVA : DWORD): DWORD;
  93. var
  94. offset : DWORD;
  95. section : PImageSectionHeader;
  96. begin
  97. section := ImgRVA2Section(dwRVA);
  98. if section = nil then
  99. result := 0
  100. else
  101. begin
  102. offset := dwRVA + section.PointerToRawData - section.VirtualAddress;
  103. result := offset;
  104. end;
  105. end;
  106.  
  107. {找到磁盘上某一个offset所映射的内存中的RVA}
  108. function TPE.Offset2RVA(dwOffset : DWORD): DWORD;
  109. var
  110. section : PImageSectionHeader;
  111. begin
  112. section := ImgOffset2Section(dwOffset);
  113. if section = nil then
  114. result := 0
  115. else
  116. result := dwOffset + section.VirtualAddress - section.PointerToRawData;
  117. end;
  118.  
  119. {返回PE文件加载到内存后,RVA地址所处的Section}
  120. function TPE.imgRVA2Section(dwRVA : DWORD) : PImageSectionHeader;
  121. var
  122. i : integer;
  123. begin
  124. for i:= 0 to imgNtHeaders.FileHeader.NumberOfSections - 1 do
  125. begin
  126. if ((dwRVA >= imgSectionHeaders[i].VirtualAddress) and (dwRVA <= (imgSectionHeaders[i].VirtualAddress + imgSectionHeaders[i].SizeOfRawData))) then
  127. begin
  128. result := @imgSectionHeaders[i];
  129. exit;
  130. end;
  131. end;
  132. result := nil;
  133. end;
  134.  
  135. {返回OFFSET地址在PE文件位于磁盘上的所落的Section}
  136. function TPE.ImgOffset2Section(dwOffset : DWORD): PImageSectionHeader;
  137. var
  138. i: integer;
  139. begin
  140. for i:=0 to imgNtHeaders.FileHeader.NumberOfSections - 1 do
  141. begin
  142. if ((dwOffset >= imgSectionHeaders[i].PointerToRawData) and (dwOffset < (imgSectionHeaders[i].PointerToRawData + imgSectionHeaders[i].SizeOfRawData))) then
  143. begin
  144. result := @ImgSectionHeaders[i];
  145. exit;
  146. end;
  147. end;
  148. result := nil;
  149. end;
  150.  
  151. {返回Offset地址在PE文件位于磁盘上所落Section的编号}
  152. function TPE.ImgOffset2SectionNum(dwOffset : DWORD): integer;
  153. var
  154. i: integer;
  155. begin
  156. for i:=0 to imgNtHeaders.FileHeader.NumberOfSections - 1 do
  157. begin
  158. if ((dwOffset >= imgSectionHeaders[i].PointerToRawData) and (dwOffset < (imgSectionHeaders[i].PointerToRawData + imgSectionHeaders[i].SizeOfRawData))) then
  159. begin
  160. result := i;
  161. exit;
  162. end;
  163. end;
  164. result := -1;
  165. end;
  166.  
  167. {增加一个新的Section,可读/写, 包含已初始化数据.}
  168. function TPE.AddNewSection(szName: string; dwSize: DWORD): PImageSectionHeader;
  169. var
  170. i : integer;
  171. roffset : DWORD;
  172. rsize : DWORD;
  173. voffset : DWORD;
  174. vsize : DWORD;
  175. begin
  176. i := imgNtHeaders.FileHeader.NumberOfSections;
  177. rsize := PEAlign(dwSize, imgNtHeaders.OptionalHeader.FileAlignment);
  178. vsize := PEAlign(rsize, imgNtHeaders.OptionalHeader.SectionAlignment);
  179. roffset := PEAlign(imgSectionHeaders[i-1].PointerToRawData + imgSectionHeaders[i-1].SizeOfRawData,
  180. imgNtHeaders.OptionalHeader.FileAlignment);
  181. voffset := PEAlign(imgSectionHeaders[i-1].VirtualAddress + imgSectionHeaders[i-1].Misc.VirtualSize,
  182. imgNtHeaders.OptionalHeader.SectionAlignment);
  183. FillChar(imgSectionHeaders[i],sizeof(TImageSectionHeader),#0);
  184. imgSectionHeaders[i].PointerToRawData := roffset;
  185. imgSectionHeaders[i].VirtualAddress := voffset;
  186. imgSectionHeaders[i].SizeOfRawData := rsize;
  187. imgSectionHeaders[i].Misc.VirtualSize := vsize;
  188. imgSectionHeaders[i].Characteristics := $C0000040;
  189.  
  190. CopyMemory(@imgSectionHeaders[i].Name[0],@szName[1],length(szName));
  191. imgSections[i] := Pointer(GLobalAlloc(GMEM_FIXED or GMEM_ZEROINIT,rsize));
  192. imgNtHeaders.FileHeader.NumberOfSections := imgNtHeaders.FileHeader.NumberOfSections + 1;
  193. result := @imgSectionHeaders[i];
  194. end;
  195.  
  196. {打开一个PE文件,按其格式分部分读入}
  197.  
  198. procedure TPE.OpenFile(filename : string);
  199. var
  200. dwBytesRead : DWORD;
  201. hFile : THANDLE;
  202. sectionNum : DWORD;
  203. i : integer;
  204. firstSectionOffset : DWORD;
  205. dwOffset : DWORD;
  206. begin
  207. pMem := nil;
  208. hFile := CreateFile(PChar(filename),GENERIC_READ, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
  209. if hFile = INVALID_HANDLE_VALUE then
  210. begin
  211. exit;
  212. end;
  213. dwFileSize := GetFileSize(hFile,0);
  214. if dwFileSize = 0 then
  215. begin
  216. CloseHandle(hFile);
  217. exit;
  218. end;
  219. pMem := Pointer(GlobalAlloc(GMEM_FIXED or GMEM_ZEROINIT, dwFileSize));
  220. if dwFileSize = 0 then
  221. begin
  222. CloseHandle(hFile);
  223. exit;
  224. end;
  225. ReadFile(hFile,pMem^,dwFileSize,dwBytesRead,nil);
  226. CloseHandle(hFile);
  227. CopyMemory(@imgDosHeader,pMem,sizeof(IMAGE_DOS_HEADER));
  228. dwDosStubSize := imgDosHeader._lfanew - sizeof(IMAGE_DOS_HEADER);
  229. dwDosStubOffset := sizeof(IMAGE_DOS_HEADER);
  230. getMem(pDosStub,dwDosStubSize);
  231. if (dwDosStubSize and $80000000) = $00000000 then
  232. begin
  233. copyMemory(pDosStub,pointer(DWORD(pMem) + dwDosStubOffset), dwDosStubSize);
  234. end;
  235. copyMemory(@imgNtHeaders,pointer(DWORD(pMem)+imgDosHeader._lfanew),sizeof(IMAGE_NT_HEADERS));
  236. firstSectionOffset := imgDosHeader._lfanew + sizeof(IMAGE_NT_HEADERS);
  237. if imgDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then
  238. begin
  239. GlobalFree(DWORD(pMem));
  240. exit;
  241. end;
  242. SectionNum := imgNtHeaders.FileHeader.NumberOfSections;
  243. for i:=0 to SectionNum -1 do
  244. begin
  245. CopyMemory(@imgSectionHeaders[i],pointer(DWORD(pMem)+ firstSectionOffset + i * sizeof(IMAGE_SECTION_HEADER)),sizeof(IMAGE_SECTION_HEADER));
  246. end;
  247. for i:=0 to SectionNum -1 do
  248. begin
  249. imgSections[i] := Pointer(GlobalAlloc(GMEM_FIXED or GMEM_ZEROINIT,PEAlign(imgSectionHeaders[i].SizeOfRawData,imgNtHeaders.OptionalHeader.FileAlignment)));
  250. copyMemory(imgSections[i],pointer(DWORD(pMem)+imgSectionHeaders[i].PointerToRawData), imgSectionHeaders[i].SizeOfRawData);
  251. end;
  252.  
  253. if imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress <> 0 then
  254. begin
  255. dwOffset := RVA2Offset(imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
  256. copymemory(@imgTLSDirectory,pointer(DWORD(pMem) + dwOffset), sizeof(IMAGE_TLS_DIRECTORY32));
  257. end;
  258. GlobalFree(DWORD(pMem));
  259. end;
  260.  
  261. procedure TPE.SaveFile(filename : string);
  262. var
  263. dwBytesWritten : DWORD;
  264. i : integer;
  265. dwRO_first_section : DWORD;
  266. sectionNum : DWORD;
  267. hFile : THANDLE;
  268. begin
  269. hFile := CreateFile(PChar(filename),GENERIC_WRITE, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
  270. if hFile = INVALID_HANDLE_VALUE then
  271. begin
  272. hFile := CreateFile(PChar(filename), GENERIC_WRITE, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,0);
  273. if hFile = INVALID_HANDLE_VALUE then
  274. exit;
  275. end;
  276. AlignmentSections;
  277. i := imgNtHeaders.FileHeader.NumberOfSections;
  278. dwFileSize := imgSectionHeaders[i-1].PointerToRawData + imgSectionHeaders[i-1].SizeOfRawData;
  279. pMem := Pointer(GlobalAlloc(GMEM_FIXED or GMEM_ZEROINIT,dwFileSize));
  280. if pMem = nil then
  281. begin
  282. CloseHandle(hFile);
  283. exit;
  284. end;
  285. copyMemory(pMem,@imgDosHeader,sizeof(IMAGE_DOS_HEADER));
  286. if (dwDOSStubSize and $80000000) = $00000000 then
  287. copyMemory(pointer(DWORD(pMem) + dwDosStubOffset), pDosStub, dwDosStubSize);
  288. copyMemory(pointer(DWORD(pMem)+imgDosHeader._lfanew), @imgNtHeaders, sizeof(IMAGE_NT_HEADERS));
  289. dwRO_first_section := imgDosHeader._lfanew + sizeof(IMAGE_NT_HEADERS);
  290. sectionNum := imgNtHeaders.FileHeader.NumberOfSections;
  291. for i:=0 to SectionNum - 1 do
  292. begin
  293. CopyMemory(pointer(DWORD(pMem) + dwRO_first_Section + i * sizeof(IMAGE_SECTION_HEADER)), @imgSectionHeaders[i],sizeof(IMAGE_SECTION_HEADER));
  294. end;
  295. for i:=0 to SectionNum - 1 do
  296. begin
  297. CopyMemory(pointer(DWORD(pMem) + imgSectionHeaders[i].PointerToRawData), imgSections[i], ImgSectionHeaders[i].SizeOfRawData);
  298. end;
  299. SetFilePointer(hFile ,0, nil,FILE_BEGIN);
  300. writeFile(hFile,pMem^,dwFileSize, dwBytesWritten,nil);
  301. setFilePointer(hFile,dwFileSize, nil,FILE_BEGIN);
  302. setEndOfFile(hFile);
  303. CloseHandle(hFile);
  304. GlobalFree(DWORD(pMem));
  305. end;
  306.  
  307. {用来查找一段代码的标志位,在FuncCode指针开始的字符串中,查找一个DWORD的标志}
  308. function TPE.ReturnToBytePtr(FuncCode : pointer; findstr : DWORD): pointer;
  309. var
  310. tmpd : Pointer;
  311. begin
  312. asm
  313. pushad
  314. mov eax, FuncCode
  315. jmp @label1
  316. @label0:
  317. inc eax
  318. @label1:
  319. mov ebx, [eax]
  320. cmp ebx, findstr
  321. jnz @label0
  322. mov tmpd, eax
  323. popad
  324. end;
  325. result := tmpd;
  326. end;
  327.  
  328. {把一段跳转指令加入到PE文件中,先建立一个新SECTION,然后把新输入表放入新区的 }
  329. { 起始地址,把一点代码放到输入表后.然后把跳转指令加入到新Section,跳回原来的程序,}
  330. {同时使用新的输入表来取代旧的输入表 }
  331. procedure TPE.CyrptFile;
  332. var
  333. ch_temp : Pointer;
  334. i : DWORD;
  335. imgSectionHeader : PImageSectionHeader;
  336. dwNewSectionSize : DWORD;
  337. dwCodeSize : DWORD;
  338. dwCodeOffset : DWORD;
  339. begin
  340. if (imgNTHeaders.FileHeader.Characteristics and IMAGE_FILE_DLL) = IMAGE_FILE_DLL then
  341. ITMaker := TImportTableMaker.Create(IMPORT_TABLE_DLL)
  342. else
  343. ITMaker := TImportTableMaker.Create(IMPORT_TABLE_EXE);
  344.  
  345. ch_temp := Pointer(DWORD(ReturnToBytePtr(@InitPE,DYN_LOADER_START_MAGIC)) +4);
  346. dwCodeSize := DWORD(ReturnToBytePtr(@InitPE,DYN_LOADER_END_MAGIC)) - DWORD(ch_temp);
  347.  
  348. dwCodeOffset := ITMaker.dwSize;
  349. dwNewSectionSize := dwCodeSize + ITMaker.dwSize;
  350. getmem(pNewSection,dwNewSectionSize);
  351. copymemory(Pointer(DWORD(pNewSection) + dwCodeOffset), ch_temp, dwCodeSize);
  352.  
  353. imgSectionHeader := AddNewSection('.xxx',dwNewSectionSize);
  354. CopyData(imgSectionHeader.VirtualAddress);
  355.  
  356. ITMaker.Build(imgSectionHeader.VirtualAddress);
  357. copyMemory(pNewSection,ITMaker.pMem, ITMaker.dwSize);
  358. copymemory(imgSections[imgNtHeaders.FileHeader.NumberOfSections-1], pNewSection, dwNewSectionSize);
  359. imgNtHeaders.OptionalHeader.AddressOfEntryPoint := imgSectionHeader.VirtualAddress + dwCodeOffset;
  360. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress := imgSectionHeader.VirtualAddress;
  361. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size := ITMaker.dwSize;
  362. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress := 0;
  363. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size := 0;
  364. SetSectionsWritePermission;
  365. freemem(pNewSection,dwNewSectionSize);
  366. ITMaker.Free;
  367. end;
  368.  
  369. procedure TPE.CopyData(dwVirtualAddress : DWORD);
  370. var
  371. i : integer;
  372. APINum : integer;
  373. pData : Pointer;
  374. dwOffset : DWORD;
  375. len : longint;
  376. DataTable : TData;
  377. temp : byte;
  378. begin
  379. DataTable.dwReserved1 := $CCCCCCCC;
  380. if ((imgNtHeaders.FileHeader.Characteristics and IMAGE_FILE_DLL) = IMAGE_FILE_DLL) then
  381. DataTable.dwFileType := IMPORT_TABLE_DLL
  382. else
  383. DataTable.dwFileType := IMPORT_TABLE_EXE;
  384. DataTable.dwImageBase := imgNtHeaders.OptionalHeader.ImageBase;
  385. DataTable.dwOrgEntryPoint := imgNtHeaders.OptionalHeader.AddressOfEntryPoint;
  386. DataTable.dwImportVAddr := imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  387. if (imgNtHeaders.FileHeader.Characteristics and IMAGE_FILE_DLL) = IMAGE_FILE_DLL then
  388. begin
  389. DataTable.dwRelocationVAddr := imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
  390. DataTable.dwRelocationSize := imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
  391. end;
  392. pData := ReturnToBytePtr(pNewSection, DYN_LOADER_START_DATA1);
  393. if imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress <> 0 then
  394. begin
  395. CopyMemory(@DataTable.imgTLSDirectory,@imgTLSDirectory,sizeof(IMAGE_TLS_DIRECTORY32));
  396. dwOffset := DWORD(pData) - DWORD(pNewSection);
  397. dwOffset := dwOffset + sizeof(DataTable) - sizeof(IMAGE_TLS_DIRECTORY32);
  398. imgNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress := dwVirtualAddress + dwOffset;
  399. end;
  400. CopyMemory(pData,@DataTable, sizeof(TData));
  401. dwOffset := sizeof(TDATA);
  402. i := 0; APINum := 0; temp := 0;
  403. repeat
  404. len := Length(szWindowsAPIs[i]) + 1;
  405. CopyMemory(Pointer(DWORD(pData) + dwOffset),@szWindowsAPIs[i][1],len);
  406. dwOffset := dwOffset + len;
  407. repeat
  408. i := i + 1;
  409. if szWindowsAPIs[i] <> '' then
  410. begin
  411. len := length(szWindowsAPIs[i]) + 1;
  412. CopyMemory(Pointer(DWORD(pData) + dwOffset), @szWindowsAPIs[i][1],len);
  413. dwOffset := dwOffset + len;
  414. APINum := APINum + 1;
  415. end
  416. else
  417. begin
  418. CopyMemory(Pointer(DWORD(pData) + dwOffset), @temp, 1);
  419. dwOffset := dwOffset + 1;
  420. end;
  421. until szWindowsAPIs[i] = '';
  422. i := i + 1;
  423. until szWindowsAPIs[i] = '';
  424. end;
  425.  
  426. procedure TPE.SetSectionsWritePermission;
  427. var
  428. i : integer;
  429. begin
  430. for i:=0 to imgNTHeaders.FileHeader.NumberOfSections - 1 do
  431. imgSectionHeaders[i].Characteristics := $C0000040;
  432. end;
  433.  
  434. {******************************************************************************}
  435.  
  436. constructor TImportTableMaker.Create(iType : integer);
  437. begin
  438. ImportTable := TList.Create;
  439. init(iType);
  440. dwSize := GetIATSize;
  441. GetMem(pMem,dwSize);
  442. end;
  443.  
  444. destructor TImportTableMaker.Destroy;
  445. var
  446. imgImport : PImageImport;
  447. begin
  448. while ImportTable.Count > 0 do
  449. begin
  450. imgImport := PImageImport(ImportTable.Items[0]);
  451. while imgImport.ThunksList.Count > 0 do
  452. begin
  453. freeMem(imgImport.ThunksList.Items[0],32);
  454. imgImport.ThunksList.Delete(0);
  455. end;
  456. imgImport.ThunksList.Free;
  457. dispose(imgImport);
  458. ImportTable.Delete(0);
  459. end;
  460. ImportTable.Free;
  461. FreeMem(pMem,dwSize);
  462. end;
  463.  
  464. procedure TImportTableMaker.Init(iType : integer);
  465. var
  466. i : integer;
  467. IATString : pointer;
  468. imgImport : PImageImport;
  469. imgThunk : PChar;
  470. function IsStringsEnd(inx : integer) : boolean;
  471. begin
  472. result := false;
  473. case iType of
  474. IMPORT_TABLE_EXE:
  475. begin
  476. if szIATEXEStrings[inx] = '' then
  477. result := true;
  478. end;
  479. IMPORT_TABLE_DLL:
  480. begin
  481. if szIATDLLStrings[inx] = '' then
  482. result := true;
  483. end;
  484. end;
  485. end;
  486. begin
  487. i := 0;
  488. repeat
  489. New(imgImport);
  490. imgImport.ThunksList := TList.Create;
  491. case iType of
  492. IMPORT_TABLE_EXE: copyMemory(@imgImport.szLibrary[0], @szIATEXEStrings[i][1],32);
  493. IMPORT_TABLE_DLL: copyMemory(@imgImport.szLibrary[0], @szIATDLLStrings[i][1],32);
  494. end;
  495. repeat
  496. i := i + 1;
  497. if not IsStringsEnd(i) then
  498. begin
  499. getMem(imgThunk,32);
  500. fillchar(imgTHunk^,32,#0);
  501. case iType of
  502. IMPORT_TABLE_EXE: copyMemory(imgThunk,@szIATEXEStrings[i][1],32);
  503. IMPORT_TABLE_DLL: copyMemory(imgThunk,@szIATDLLStrings[i][1],32);
  504. end;
  505. imgImport.ThunksList.Add(imgThunk);
  506. end;
  507. until IsStringsEnd(i);
  508. ImportTable.Add(imgImport);
  509. i := i + 1;
  510. until IsStringsEnd(i);
  511. end;
  512.  
  513. function TImportTableMaker.GetIATSize : DWORD;
  514. var
  515. i : integer;
  516. j : integer;
  517. dwDLLNum : DWORD;
  518. dwFuncNum : DWORD;
  519. dwszDLLSize : DWORD;
  520. dwszFuncSize : DWORD;
  521. dwImportSize : DWORD;
  522. imgImport : PImageImport;
  523. begin
  524. dwDLLNum := 0; dwFuncNum := 0; dwszDLLSize := 0; dwszFuncSize := 0; dwImportSize := 0;
  525. for i:= 0 to ImportTable.Count - 1 do
  526. begin
  527. imgImport := ImportTable.Items[i];
  528. dwszDLLSize := dwszDLLSize + strlen(imgimport.szLibrary) + 1;
  529. for j:=0 to imgImport.ThunksList.Count - 1 do
  530. begin
  531. dwszFuncSize := dwszFuncSize + 2 + strlen(PChar(imgimport.ThunksList.Items[j])) + 1;
  532. dwFuncNum := dwFuncNum + 1;
  533. end;
  534. dwFuncNum := dwFuncNum + 1;
  535. dwDLLNum := dwDLLNum + 1;
  536. end;
  537. dwDLLNum := dwDLLNum + 1;
  538. dwImportSize := dwDLLnum * 20 + dwFuncNum * 4 + dwSzDLLSize + dwszFuncSize;
  539. result := dwImportSize;
  540. end;
  541.  
  542. procedure TImportTableMaker.Build(baseRVA : DWORD);
  543. var
  544. i : integer;
  545. j : integer;
  546. pITBaseRVA : DWORD;
  547. temp : DWORD;
  548. dwDLLNum : DWORD;
  549. dwDLLName : DWORD;
  550. dwDLLFirst : DWORD;
  551. dwszDLLSize : DWORD;
  552. dwIIDNum : DWORD;
  553. dwFunNum : DWORD;
  554. dwFunFirst : DWORD;
  555. dwszFuncSize : DWORD;
  556. dwFirstThunk : DWORD;
  557. dwImportSize : DWORD;
  558. imgImport : PImageImport;
  559. importDesc : TImageImportDecriptor;
  560. begin
  561. pITBaseRVA := baseRVA;
  562. importDesc.Union.OriginalFirstThunk := 0;
  563. importDesc.TimeDateStamp := 0;
  564. importDesc.ForwarderChain := 0;
  565. importDesc.Name := 0;
  566. importDesc.FirstThunk := 0;
  567. dwDLLNum := 0; dwDLLName := 0; dwDLLFirst := 0; dwszDLLSize := 0;
  568. dwIIDNum := 0; dwFunNum := 0; dwFunFirst := 0; dwszFuncSize := 0;
  569. dwFirstThunk := 0; dwImportSize := 0;
  570.  
  571. for i:= 0 to importTable.Count -1 do
  572. begin
  573. imgImport := PImageImport(importTable.Items[i]);
  574. dwszDLLSize := dwszDLLSize + strlen(imgImport.szLibrary) + 1;
  575. for j:= 0 to imgImport.ThunksList.Count - 1 do
  576. begin
  577. dwszFuncSize := dwszFuncSize + 2 + strlen(PChar(imgImport.ThunksList.Items[j])) + 1;
  578. dwFunNum := dwFunNum + 1;
  579. end;
  580. dwFunNum := dwFunNum + 1;
  581. dwDLLNum := dwDLLNum + 1;
  582. end;
  583. dwDLLNum := dwDLLNum + 1;
  584. dwImportSize := dwDLLNum * 20 + dwFunNum * 4 + dwszDLLSize + dwszFuncSize;
  585. FillMemory(pMem,dwImportSize, 0);
  586.  
  587. dwFirstThunk := dwDLLNum * 20;
  588. dwDLLFirst := dwDLLNum * 20 + dwFunNum * 4;
  589. dwFunFirst := dwDLLNum * 20 + dwFunNum * 4 + dwszDLLSize;
  590. for i := 0 to importTable.Count - 1 do
  591. begin
  592. imgImport := importTable.Items[i];
  593. importDesc.Name := pITBaseRVA + dwDLLFirst;
  594. importDesc.FirstThunk := pITBaseRVA + dwFirstThunk;
  595. CopyMemory(Pointer(DWORD(pMem) + dwIIDNum * sizeof(IMAGE_IMPORT_DESCRIPTOR)),@importDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR));
  596. CopyMemory(Pointer(DWORD(pMem) + dwDLLFirst),@imgImport.szLibrary[0],strlen(imgImport.szLibrary) + 1);
  597. for j:=0 to imgimport.ThunksList.Count - 1 do
  598. begin
  599. temp := pITBaseRVA + dwFunFirst;
  600. CopyMemory(Pointer(DWORD(pMem) + dwFirstThunk),@temp,4);
  601. CopyMemory(Pointer(DWORD(pMem) + dwFunFirst + 2), PChar(imgImport.ThunksList.Items[j]),strlen(imgImport.ThunksList.Items[j]) + 1);
  602. dwFunFirst := dwFunFirst + 2 + strlen(imgImport.ThunksList.Items[j]) + 1;
  603. dwFirstThunk := dwFirstThunk + 4;
  604. end;
  605. temp := 0;
  606. CopyMemory(Pointer(DWORD(pMem) + dwFirstThunk),@temp, 4);
  607. dwFirstThunk := dwFirstTHunk + 4;
  608. dwDLLFirst := dwDLLFirst + strlen(imgImport.szLibrary) + 1;
  609. dwIIDNum := dwIIDNum + 1;
  610. end;
  611. importDesc.Name := 0;
  612. importDesc.FirstThunk := 0;
  613. CopyMemory(Pointer(DWORD(pMem)+dwIIDNum * sizeof(IMAGE_IMPORT_DESCRIPTOR)), @importDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR));
  614. end;
  615.  
  616. end.
  617.  
  618. {************************************************************************************************************}
  619.  
  620. PEint单元
  621.  
  622. unit PEInit;
  623.  
  624. interface
  625. uses windows;
  626.  
  627. procedure InitPE; stdcall;
  628.  
  629. implementation
  630.  
  631. {一段要嵌入到PE文件中的指令}
  632. {标志位的作用是用来找到找到从开始标志位后到结束标志位之间的指令大小及开始地址}
  633. {这段代码如果用在VC中,则要设置链接选项/INCREMENTAL LINK OFF}
  634. procedure InitPE; stdcall;
  635. begin
  636. asm
  637. {开始标志位}
  638. DB $A9 DB $51 DB $DE DB $C0
  639. @Main_0:
  640. pushad;
  641. call @Main_1
  642. @Main_1:
  643. pop ebp
  644. sub ebp, offset @main_1
  645.  
  646. {**********************支持DLLOCX等****************************************}
  647. @_support_dll_0:
  648. jmp @_support_dll_1 {// nop; nop; // in the secon time OEP 第一次加载后,}
  649. {这句会被改成 nop; nop;在DLL被卸载的时候,会直接调用jmp @_support_dll_2}
  650. jmp @_support_dll_2
  651. @_support_dll_1:
  652. test [ebp + @_p_dwFileType],0001h // IMPORT_TABLE_DLL
  653. jz @_no_dll_pe_file_0
  654. mov eax,[esp+24h]
  655. mov ebx,[esp+34h]
  656. cmp eax,ebx
  657. ja @_no_dll_pe_file_0
  658. cmp word ptr [eax], IMAGE_DOS_SIGNATURE
  659. jne @_no_dll_pe_file_0
  660. mov [ebp + @_RO_dwImageBase],eax
  661.  
  662. @_no_dll_pe_file_0:
  663.  
  664. // 获取输入表中的LoadLibrary 和 GetProcAddress来建立函数跳转表
  665. mov eax, DWORD PTR [ebp + @_RO_dwImageBase]
  666.  
  667. add eax, [eax + 03Ch]
  668.  
  669. add eax, 080h
  670. mov ecx, [eax]
  671. add ecx, [ebp + @_RO_dwImageBase]
  672. add ecx, 010h
  673. mov eax, [ecx]
  674. add eax, [ebp + @_RO_dwImageBase]
  675. mov ebx, [eax]
  676. mov [ebp + @_p_LoadLibrary],ebx
  677. add eax, 04h
  678. mov ebx, [eax]
  679. mov [ebp + @_p_GetProcAddress], ebx
  680.  
  681. call @_api_load // 加载插入功能代码所需要的DLL和函数跳转表
  682.  
  683. //***************************功能性代码***************************************
  684. push MB_OK or MB_ICONINFORMATION
  685. lea eax,[ebp + @_p_szCaption]
  686. push eax
  687. lea eax,[ebp + @_p_szText]
  688. push eax
  689. push 0000h
  690. call @_jmp_MessageBox
  691. //****************************************************************************
  692.  
  693. {将在内存中的PE文件的NTHeader头改为可读写}
  694. mov edi, [ebp + @_RO_dwImageBase]
  695. add edi, [edi + 03Ch]
  696. lea eax, [ebp + @_p_ptempbuffer]
  697. push eax
  698. push PAGE_READWRITE
  699. push [edi + 54h]
  700. push [ebp + @_RO_dwImageBase]
  701. call @_jmp_VirtualProtect
  702.  
  703. call @_it_fixup // 为被插入的程序建立内存中的输入表
  704.  
  705. {判断是否是DLL}
  706. mov edi,[ebp + @_RO_dwImageBase]
  707. add edi,[edi+03Ch]
  708. mov ax,word ptr [edi+016h]
  709.  
  710. test ax,IMAGE_FILE_DLL
  711. jz @_no_dll_pe_file_1
  712.  
  713. call @_reloc_fixup // 为被捆绑的程序修正重定位表.因为EXE一般不需要,只在DLL的时候需要。
  714.  
  715. mov ax,9090h // 为DLL建立卸载时候的入口点
  716. mov word ptr [ebp + @_support_dll_0],ax
  717. @_no_dll_pe_file_1:
  718.  
  719. @_support_dll_2:
  720.  
  721. //--------- 利用SEH异常转入程序入口点 ---------
  722. mov eax, [ebp + @_RO_dwImageBase]
  723. add eax, DWORD PTR [ebp + @_RO_dwOrgEntryPoint]
  724. mov DWORD PTR [esp + 10h], eax
  725. lea eax, [ebp + @_except_handler1_oep_jump]
  726. mov DWORD PTR [esp + 1ch],eax
  727. popad
  728. push eax
  729. xor eax,eax
  730. push DWORD PTR FS:[0]
  731. mov DWORD PTR FS:[0], ESP
  732. {注册完异常处理回调函数,开始调用INT 3 触发异常,异常发生后,}
  733. {线程的栈被保护起来,原来存有真正OEP地址的EBX也被保存起来}
  734. DB $CC
  735. DB $CC
  736. DB $CC
  737. DB $CC
  738.  
  739. {eax中返回字符串的长度}
  740. @_strlen:
  741. push ebp
  742. mov ebp,esp
  743. push ecx
  744. push esi
  745. push ebx
  746. mov esi,[ebp+08h]
  747.  
  748. mov ecx,255// -> Length
  749. xor ebx,ebx
  750. @_strlenloop:
  751. lods byte ptr ds:[esi]
  752. cmp al,00h
  753. jz @_endbufstrlen
  754. inc ebx
  755. loop @_strlenloop
  756. @_endbufstrlen:
  757. mov eax,ebx
  758. inc eax
  759. pop ebx
  760. pop esi
  761. pop ecx
  762. mov esp,ebp
  763. pop ebp
  764. ret
  765.  
  766. {*********************为被插入代码的程序修正重定位表*******************************}
  767. @_reloc_fixup:
  768. mov eax,[ebp + @_RO_dwImageBase]
  769. mov edx,eax
  770. mov ebx,eax
  771. add ebx,[ebx+3Ch]
  772. mov ebx,[ebx+034h]
  773. sub edx,ebx
  774. je @_reloc_fixup_end
  775. mov ebx,[ebp + @_p_dwRelocationVirtualAddress]
  776. test ebx,ebx
  777. jz @_reloc_fixup_end
  778. add ebx,eax
  779. @_reloc_fixup_block:
  780. mov eax,[ebx+004h]
  781. test eax,eax
  782. jz @_reloc_fixup_end
  783. lea ecx,[eax-008h]
  784. shr ecx,001h
  785. lea edi,[ebx+008h]
  786. @_reloc_fixup_do_entry:
  787. movzx eax,word ptr [edi]
  788. push edx
  789. mov edx,eax
  790. shr eax,00Ch
  791.  
  792. mov esi,[ebp + @_RO_dwImageBase]
  793. and dx,00FFFh
  794. add esi,[ebx]
  795. add esi,edx
  796. pop edx
  797.  
  798. @_reloc_fixup_HIGH:
  799. dec eax
  800. jnz @_reloc_fixup_LOW
  801. mov eax,edx
  802. shr eax,010h //HIWORD(Delta)
  803. jmp @_reloc_fixup_LOW_fixup
  804.  
  805. @_reloc_fixup_LOW:
  806. dec eax
  807. jnz @_reloc_fixup_HIGHLOW
  808. movzx eax,dx //LOWORD(Delta)
  809. @_reloc_fixup_LOW_fixup:
  810. add word ptr [esi],ax
  811. jmp @_reloc_fixup_next_entry
  812.  
  813. @_reloc_fixup_HIGHLOW:
  814. dec eax
  815. jnz @_reloc_fixup_next_entry
  816. add [esi],edx
  817.  
  818. @_reloc_fixup_next_entry:
  819. inc edi
  820. inc edi //Entry++
  821. loop @_reloc_fixup_do_entry
  822.  
  823. @_reloc_fixup_next_base:
  824. add ebx,[ebx+004h] //ImageBaseRelocation + ImageBaseRelocation.SizeOfBlock
  825. jmp @_reloc_fixup_block
  826. @_reloc_fixup_end:
  827. ret
  828.  
  829. {**************为捆绑的程序在内存中建立IAT表*********************************}
  830. {1. 加载输入表中对应的DLL }
  831. {2. 加载输入表里对应DLL的输入函数。 }
  832. {3. 讲函数的内存地址放入输入表的FirstThunk里,建立IAT }
  833. @_it_fixup:
  834. mov ebx,[ebp + @_p_dwImportVirtualAddress]
  835. test ebx,ebx
  836. jz @_it_fixup_end
  837. mov esi,[ebp + @_RO_dwImageBase]
  838. add ebx,esi
  839. @_it_fixup_get_lib_address_loop:
  840. mov eax,[ebx+00Ch]
  841. test eax,eax
  842. jz @_it_fixup_end
  843.  
  844. mov ecx,[ebx+010h]
  845. add ecx,esi
  846. mov [ebp + @_p_dwThunk],ecx
  847. mov ecx,[ebx]
  848. test ecx,ecx
  849. jnz @_it_fixup_table
  850. mov ecx,[ebx + 010h]
  851. @_it_fixup_table:
  852. add ecx,esi
  853. mov [ebp + @_p_dwHintName],ecx
  854. add eax,esi
  855. push eax
  856. mov eax,offset @_p_LoadLibrary
  857. call [ebp+eax]
  858.  
  859. test eax,eax
  860. jz @_it_fixup_end
  861. mov edi,eax
  862. @_it_fixup_get_proc_address_loop:
  863. mov ecx,[ebp + @_p_dwHintName]
  864. mov edx,[ecx]
  865. test edx,edx
  866. jz @_it_fixup_next_module
  867. test edx,80000000h
  868. jz @_it_fixup_by_name
  869. and edx,07FFFFFFFh
  870. jmp @_it_fixup_get_addr
  871. @_it_fixup_by_name:
  872. add edx,esi
  873. inc edx
  874. inc edx
  875. @_it_fixup_get_addr:
  876. push edx
  877. push edi
  878. mov eax,offset @_p_GetProcAddress
  879. call [ebp+eax]
  880.  
  881. mov ecx,[ebp + @_p_dwThunk]
  882. mov [ecx],eax
  883. add dword ptr [ebp + @_p_dwThunk],004h
  884. add dword ptr [ebp + @_p_dwHintName],004h
  885. jmp @_it_fixup_get_proc_address_loop
  886. @_it_fixup_next_module:
  887. add ebx,014h
  888. jmp @_it_fixup_get_lib_address_loop
  889. @_it_fixup_end:
  890. ret
  891.  
  892. {***************加载动态库,然后建立其输入函数的跳转表***********************}
  893. @_api_load:
  894. lea edi, [ebp + @_p_szKernel32]
  895. lea ebx, [ebp + @_p_GetModuleHandle]
  896. lea ecx, [ebp + @_jmp_GetModuleHandle]
  897. add ecx, 02h
  898. @_api_get_lib_address_loop:
  899. push ecx
  900. push edi
  901. mov eax, offset @_p_LoadLibrary
  902. call [ebp + eax]
  903. pop ecx
  904. mov esi, eax
  905. push edi
  906. call @_strlen
  907. add esp, 04h
  908. add edi, eax
  909. @_api_get_proc_address_loop:
  910. push ecx
  911. push edi
  912. push esi
  913. mov eax, offset @_p_GetProcAddress
  914. call [ebp + eax]
  915. pop ecx
  916. mov [ebx], eax
  917. mov [ecx], ebx
  918. add ebx, 04h
  919. add ecx, 06h
  920. push edi
  921. call @_strlen
  922. add esp, 04h
  923. add edi, eax
  924. mov al, byte ptr [edi]
  925. test al,al
  926. jnz @_api_get_proc_address_loop
  927. inc edi
  928. mov al, byte ptr [edi]
  929. test al, al
  930. jnz @_api_get_lib_address_loop
  931. ret
  932.  
  933. {SEH异常处理回调函数的有四个参数,分别为ExceptionRecord, SEH, Context, }
  934. {DispatcherContext,先压入下一个指令的地址,然后根据被压入栈的这四个参数中 }
  935. {Context

四、测试。

可以对EXE文件和DLL文件进行代码插入。当被插入的EXE文件或DLL文件运行或被调用的时候,都会先跳出一个对话框:

然后再运行或调用被插入的EXE或DLL文件。

http://blog.csdn.net/suiyunonghen/article/details/3860206

PE头的应用---插入代码到EXE或DLL文件中的更多相关文章

  1. C# .exe和.dll文件图标资源提取工具

    Windows 可执行文件(.exe)和动态库文件(.dll)图标资源提取工具 GitHub 功能 图标资源预览 图标资源导出(仅支持导出 PNG 格式) 代码 获取图标资源使用了 Win32 API ...

  2. 有关windows系统的EXE和DLL文件说法错误

    正确答案: B C   你的答案: C (错误) EXE和DLL文件都是PE文件 EXE不能有导出函数,DLL可以有导出函数 EXE有x86和x64之分,则DLL没有 EXE可以单独运行,DLL则不行 ...

  3. 使用ILmerge合并Exe、Dll文件的帮助类

    原文:使用ILmerge合并Exe.Dll文件的帮助类 using System; using System.Collections.Generic; using System.Text; using ...

  4. .net Reactor之exe、dll文件混淆

    .net Reactor之exe.dll文件混淆 .net Reactor的主要功能: 1.是对dll文件.exe文件进行反编译混淆 2.对dll进行内部加锁,限制其使用的固定机器.固定时间.部署次数 ...

  5. 通过AssemblyResolve事件打包合并exe和dll文件

    使用WPF开发的安装包,在创建快捷方式的时候,需要用到COM程序集Windows Script Host Object Model,引用COM程序集后,会在debug目录生成Interop.IWshR ...

  6. 怎样判断一个exe可执行程序(dll文件)是32位的还是64位的

    看到一个比较简单粗暴的方式,做个记录. 直接用记事本或者notepad++(文本编辑软件都可)打开exe文件(dll文件), 会有很多乱码,接下来只需要在第二段中找到PE两个字母,在其后的不远出会出现 ...

  7. 如何将一个Form中的代码拆分到多个文件中

    https://social.msdn.microsoft.com/Forums/en-US/64c77755-b0c1-4447-8ac9-b5a63a681b78/partial-class-fo ...

  8. 将exe和dll文件打包成单一的启动文件

    当我们用 VS 或其它编程工具生成了可执行exe要运行它必须要保证其目录下有一大堆dll库文件,看起来很不爽,用专业的安装程序生成软件又显得繁琐,下面这个方法教你如何快速把exe文件和dll文件打包成 ...

  9. Linux:使用awk命令获取文本的某一行,某一列;sed插入指定的内容到指定文件中

    awk相关用法: 1.打印文件的第一列(域)                 : awk '{print $1}' filename2.打印文件的前两列(域)                 : aw ...

随机推荐

  1. 无缝滚动 jQuery经典代码 (收藏)

    <script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4 ...

  2. 勉強すべきURL

    http://www.atmarkit.co.jp/ait/articles/1403/19/news034_2.html http://webdesignerwork.jp/web/responsi ...

  3. HTML5兼容IE各版本的写法

    IE下判断IE版本的语句 <!--[if lte IE 6]> <![endif]--> IE6及其以下版本可见   <!--[if lte IE 7]> < ...

  4. JS中的prototype属性

    JavaScript是基于对象的,任何元素都可以看成对象.然而,类型和对象是不同的.本文中,我们除了讨论类型和对象的一些特点之外,更重要的 是研究  如何写出好的并且利于重用的类型.毕竟,JavaSc ...

  5. J2SE知识点摘记-数据库(二)

    一.          查询数据 注意sql的内容. 通过ResultSet接口保存全部的查询结果,通过Statement接口中的executeQuery()方法查询.查询之后需要分别取出.通过nex ...

  6. MRP工作台任务下达之计划组为必输

    应用 Oracle   Manufacturing Planning 层 Level Function 函数名 Funcgtion Name MRPFPPWB 表单名 Form   Name MRPS ...

  7. openStack use

    <1,project security> security groyps Security groups--> are sets of IP filter rules() that ...

  8. linux创建文件树,孩子兄弟树(或广义表),创建文件树及其訪问

    假设在Linux下要訪问一个目录. 我们须要知道一下系统调用. 1.opendir(path); //注意path是绝对路径 2.ptr=readdir(dir);//dir 为opendir();正 ...

  9. B树、B-树、B+树、B*树都是什么(转)

    B树        即二叉搜索树:        1.所有非叶子结点至多拥有两个儿子(Left和Right):        2.所有结点存储一个关键字:        3.非叶子结点的左指针指向小于 ...

  10. 【每日一摩斯】-Troubleshooting: High CPU Utilization (164768.1) - 系列6

    如果问题是一个正运行的缓慢的查询SQL,那么就应该对该查询进行调优,避免它耗费过高的CPU资源.如果它做了许多的hash连接和全表扫描,那么就应该添加索引以提高效率. 下面的文章可以帮助判断查询的问题 ...