从内存中加载DLL DELPHI版

雨点打透心脏的1/2处 2021-11-23 18:24 565阅读 0赞
  1. //从内存中加载DLL DELPHI版
  2. unit MemLibrary;
  3. interface
  4. uses
  5. Windows;
  6. function memLoadLibrary(pLib: Pointer): DWord;
  7. function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;
  8. function memFreeLibrary(dwHandle: DWord): Boolean;
  9. implementation
  10. procedure ChangeReloc(baseorgp, basedllp, relocp: pointer; size: cardinal);
  11. type
  12. TRelocblock = record
  13. vaddress: integer;
  14. size: integer;
  15. end;
  16. PRelocblock = ^TRelocblock;
  17. var
  18. myreloc: PRelocblock;
  19. reloccount: integer;
  20. startp: ^word;
  21. i: cardinal;
  22. p: ^cardinal;
  23. dif: cardinal;
  24. begin
  25. myreloc := relocp;
  26. dif := cardinal(basedllp)-cardinal(baseorgp);
  27. startp := pointer(cardinal(relocp)+8);
  28. while myreloc^.vaddress <> 0 do
  29. begin
  30. reloccount := (myreloc^.size-8) div sizeof(word);
  31. for i := 0 to reloccount-1 do
  32. begin
  33. if (startp^ xor $3000 < $1000) then
  34. begin
  35. p := pointer(myreloc^.vaddress+startp^ mod $3000+integer(basedllp));
  36. p^ := p^+dif;
  37. end;
  38. startp := pointer(cardinal(startp)+sizeof(word));
  39. end;
  40. myreloc := pointer(startp);
  41. startp := pointer(cardinal(startp)+8);
  42. end;
  43. end;
  44. procedure CreateImportTable(dllbasep, importp: pointer); stdcall;
  45. type
  46. timportblock = record
  47. Characteristics: cardinal;
  48. TimeDateStamp: cardinal;
  49. ForwarderChain: cardinal;
  50. Name: pchar;
  51. FirstThunk: pointer;
  52. end;
  53. pimportblock = ^timportblock;
  54. var
  55. myimport: pimportblock;
  56. thunksread, thunkswrite: ^pointer;
  57. dllname: pchar;
  58. dllh: thandle;
  59. old: cardinal;
  60. begin
  61. myimport := importp;
  62. while (myimport^.FirstThunk <> nil) and (myimport^.Name <> nil) do
  63. begin
  64. dllname := pointer(integer(dllbasep)+integer(myimport^.name));
  65. dllh := LoadLibrary(dllname);
  66. thunksread := pointer(integer(myimport^.FirstThunk)+integer(dllbasep));
  67. thunkswrite := thunksread;
  68. if integer(myimport^.TimeDateStamp) = -1 then
  69. thunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));
  70. while (thunksread^ <> nil) do
  71. begin
  72. if VirtualProtect(thunkswrite,4,PAGE_EXECUTE_READWRITE,old) then
  73. begin
  74. if (cardinal(thunksread^) and $80000000 <> 0) then
  75. thunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) else
  76. thunkswrite^ := GetProcAddress(dllh,pchar(integer(dllbasep)+integer(thunksread^)+2));
  77. VirtualProtect(thunkswrite,4,old,old);
  78. end;
  79. inc(thunksread,1);
  80. inc(thunkswrite,1);
  81. end;
  82. myimport := pointer(integer(myimport)+sizeof(timportblock));
  83. end;
  84. end;
  85. function memLoadLibrary(pLib: Pointer): DWord;
  86. var
  87. DllMain : function (dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;
  88. IDH : PImageDosHeader;
  89. INH : PImageNtHeaders;
  90. SEC : PImageSectionHeader;
  91. dwSecCount : DWord;
  92. dwLen : DWord;
  93. dwmemsize : DWord;
  94. i : Integer;
  95. pAll : Pointer;
  96. begin
  97. Result := 0;
  98. IDH := pLib;
  99. if isBadReadPtr(IDH, SizeOf(TImageDosHeader)) or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
  100. Exit;
  101. INH := pointer(cardinal(pLib)+cardinal(IDH^._lfanew));
  102. if isBadReadPtr(INH, SizeOf(TImageNtHeaders)) or (INH^.Signature <> IMAGE_NT_SIGNATURE) then
  103. Exit;
  104. // if (pReserved <> nil) then
  105. // dwLen := Length(pReserved)+1
  106. // else
  107. dwLen := 0;
  108. SEC := Pointer(Integer(INH)+SizeOf(TImageNtHeaders));
  109. dwMemSize := INH^.OptionalHeader.SizeOfImage;
  110. if (dwMemSize = 0) then Exit;
  111. pAll := VirtualAlloc(nil,dwMemSize+dwLen,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
  112. if (pAll = nil) then Exit;
  113. dwSecCount := INH^.FileHeader.NumberOfSections;
  114. CopyMemory(pAll,IDH,DWord(SEC)-DWord(IDH)+dwSecCount*SizeOf(TImageSectionHeader));
  115. // CopyMemory(Pointer(DWord(pAll) + dwMemSize),pReserved,dwLen-1);
  116. CopyMemory(Pointer(DWord(pAll) + dwMemSize),nil,dwLen-1);
  117. for i := 0 to dwSecCount-1 do
  118. begin
  119. CopyMemory(Pointer(DWord(pAll)+SEC^.VirtualAddress),
  120. Pointer(DWord(pLib)+DWord(SEC^.PointerToRawData)),
  121. SEC^.SizeOfRawData);
  122. SEC := Pointer(Integer(SEC)+SizeOf(TImageSectionHeader));
  123. end;
  124. if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then
  125. ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase),
  126. pAll,
  127. Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
  128. INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
  129. CreateImportTable(pAll, Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
  130. @DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint+DWord(pAll));
  131. // if (INH^.OptionalHeader.AddressOfEntryPoint <> 0) and (bDllMain) then
  132. if INH^.OptionalHeader.AddressOfEntryPoint <> 0 then
  133. begin
  134. try
  135. // if (pReserved <> nil) then
  136. // DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)
  137. // else
  138. DllMain(DWord(pAll),DLL_PROCESS_ATTACH,0);
  139. except
  140. end;
  141. end;
  142. Result := DWord(pAll);
  143. end;
  144. function memFreeLibrary(dwHandle: DWord): Boolean;
  145. var
  146. IDH: PImageDosHeader;
  147. INH: PImageNTHeaders;
  148. begin
  149. Result := false;
  150. if (dwHandle = 0) then
  151. Exit;
  152. IDH := Pointer(dwHandle);
  153. if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
  154. Exit;
  155. INH := Pointer(DWord(IDH^._lfanew)+DWord(IDH));
  156. if (INH^.Signature <> IMAGE_NT_SIGNATURE) then
  157. Exit;
  158. if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then
  159. Result := True;
  160. end;
  161. function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;
  162. var
  163. NtHeader : PImageNtHeaders;
  164. DosHeader : PImageDosHeader;
  165. DataDirectory : PImageDataDirectory;
  166. ExportDirectory : PImageExportDirectory;
  167. i : Integer;
  168. iExportOrdinal : Integer;
  169. ExportName : String;
  170. dwPosDot : DWord;
  171. dwNewmodule : DWord;
  172. pFirstExportName : Pointer;
  173. pFirstExportAddress: Pointer;
  174. pFirstExportOrdinal: Pointer;
  175. pExportAddr : PDWord;
  176. pExportNameNow : PDWord;
  177. pExportOrdinalNow : PWord;
  178. begin
  179. Result := nil;
  180. if pFunctionName = nil then Exit;
  181. DosHeader := Pointer(dwLibHandle);
  182. if isBadReadPtr(DosHeader,sizeof(TImageDosHeader)) or (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
  183. Exit; {
  184. Wrong PE (DOS) Header}
  185. NtHeader := Pointer(DWord(DosHeader^._lfanew)+DWord(DosHeader));
  186. if isBadReadPtr(NtHeader, sizeof(TImageNTHeaders)) or (NtHeader^.Signature <> IMAGE_NT_SIGNATURE) then
  187. Exit; {
  188. Wrong PW (NT) Header}
  189. DataDirectory := @NtHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  190. if (DataDirectory = nil) or (DataDirectory^.VirtualAddress = 0) then
  191. Exit; {
  192. Library has no exporttable}
  193. ExportDirectory := Pointer(DWord(DosHeader) + DWord(DataDirectory^.VirtualAddress));
  194. if isBadReadPtr(ExportDirectory,SizeOf(TImageExportDirectory)) then
  195. Exit;
  196. pFirstExportName := Pointer(DWord(ExportDirectory^.AddressOfNames)+DWord(DosHeader));
  197. pFirstExportOrdinal := Pointer(DWord(ExportDirectory^.AddressOfNameOrdinals)+DWord(DosHeader));
  198. pFirstExportAddress := Pointer(DWord(ExportDirectory^.AddressOfFunctions)+DWord(DosHeader));
  199. if (integer(pFunctionName) > $FFFF) then {
  200. is FunctionName a PChar?}
  201. begin
  202. iExportOrdinal := -1; {
  203. if we dont find the correct ExportOrdinal}
  204. for i := 0 to ExportDirectory^.NumberOfNames-1 do {
  205. for each export do}
  206. begin
  207. pExportNameNow := Pointer(Integer(pFirstExportName)+SizeOf(Pointer)*i);
  208. if (not isBadReadPtr(pExportNameNow,SizeOf(DWord))) then
  209. begin
  210. ExportName := PChar(pExportNameNow^+ DWord(DosHeader));
  211. if (ExportName = pFunctionName) then {
  212. is it the export we search? Calculate the ordinal.}
  213. begin
  214. pExportOrdinalNow := Pointer(Integer(pFirstExportOrdinal)+SizeOf(Word)*i);
  215. if (not isBadReadPtr(pExportOrdinalNow,SizeOf(Word))) then
  216. iExportOrdinal := pExportOrdinalNow^;
  217. end;
  218. end;
  219. end;
  220. end else{
  221. no PChar, calculate the ordinal directly}
  222. iExportOrdinal := DWord(pFunctionName)-DWord(ExportDirectory^.Base);
  223. if (iExportOrdinal < 0) or (iExportOrdinal > Integer(ExportDirectory^.NumberOfFunctions)) then
  224. Exit; {
  225. havent found the ordinal}
  226. pExportAddr := Pointer(iExportOrdinal*4+Integer(pFirstExportAddress));
  227. if (isBadReadPtr(pExportAddr,SizeOf(DWord))) then
  228. Exit;
  229. {
  230. Is the Export outside the ExportSection? If not its NT spezific forwared function}
  231. if (pExportAddr^ < DWord(DataDirectory^.VirtualAddress)) or
  232. (pExportAddr^ > DWord(DataDirectory^.VirtualAddress+DataDirectory^.Size)) then
  233. begin
  234. if (pExportAddr^ <> 0) then {
  235. calculate export address}
  236. Result := Pointer(pExportAddr^+DWord(DosHeader));
  237. end
  238. else
  239. begin {
  240. forwarded function (like kernel32.EnterCriticalSection -> NTDLL.RtlEnterCriticalSection)}
  241. ExportName := PChar(dwLibHandle+pExportAddr^);
  242. dwPosDot := Pos('.',ExportName);
  243. if (dwPosDot > 0) then
  244. begin
  245. dwNewModule := GetModuleHandle(PChar(Copy(ExportName,1,dwPosDot-1)));
  246. if (dwNewModule = 0) then
  247. dwNewModule := LoadLibrary(PChar(Copy(ExportName,1,dwPosDot-1)));
  248. if (dwNewModule <> 0) then
  249. result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));
  250. end;
  251. end;
  252. end;
  253. end.

转载于:https://www.cnblogs.com/MaxWoods/p/3706194.html

发表评论

表情:
评论列表 (有 0 条评论,565人围观)

还没有评论,来说两句吧...

相关阅读