WIN7 D2010 LITE 测试 result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName)))); 出错 改成 result := GetProcAddress(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));
本人初学者,测试例子代码也出现了问题 后来百度了一下VirtualFree函数 貌似第一个参数是个地址(不是指针) 所以 把MemLibrary.pas的 if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then 改成 if VirtualFree(@dwHandle,INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then 即可 就是说Pointer(dwHandle) 改成 @dwHandle
procedure TForm1.Button1Click(Sender: TObject); var h: integer; mb: pointer; ms: TMemoryStream; begin ms := TMemoryStream.Create; ms.LoadFromFile('f:\user32.dll'); h := memLoadLibrary(ms.Memory);
if h > 0 then begin mb := memGetProcAddress(h, 'MessageBoxA'); if mb <> nil then mbf(mb)(handle, 'test', 'test', mb_ok); end;
function GetProcAddressX(dwLibraryHandle: DWord; pFunctionName: PChar): Pointer; stdcall; var NtHeader : PImageNtHeaders; DosHeader : PImageDosHeader; DataDirectory : PImageDataDirectory; ExportDirectory : PImageExportDirectory; i : Integer; iExportOrdinal : Integer; ExportName : String; dwPosDot : DWord; dwNewmodule : DWord; pFirstExportName : Pointer; pFirstExportAddress: Pointer; pFirstExportOrdinal: Pointer; pExportAddr : PDWord; pExportNameNow : PDWord; pExportOrdinalNow : PWord; begin Result := nil; DosHeader := Pointer(dwLibraryHandle); if (pFunctionName = nil) then Exit;
if (isBadReadPtr(DosHeader,sizeof(TImageDosHeader)) or (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE)) then Exit; {Wrong PE (DOS) Header}
NtHeader := Pointer(DWord(DosHeader^._lfanew)+DWord(DosHeader)); if (isBadReadPtr(NtHeader, sizeof(TImageNTHeaders)) or (NtHeader^.Signature <> IMAGE_NT_SIGNATURE)) then Exit; {Wrong PW (NT) Header}
DataDirectory := @NtHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; if (DataDirectory = nil) or (DataDirectory^.VirtualAddress = 0) then Exit; {Library has no exporttable}
ExportDirectory := Pointer(DWord(DosHeader) + DWord(DataDirectory^.VirtualAddress)); if isBadReadPtr(ExportDirectory,SizeOf(TImageExportDirectory)) then Exit;
if (integer(pFunctionName) > $FFFF) then {is FunctionName a PChar?} begin iExportOrdinal := -1; {if we dont find the correct ExportOrdinal} for i := 0 to ExportDirectory^.NumberOfNames-1 do {for each export do} begin pExportNameNow := Pointer(Integer(pFirstExportName)+SizeOf(Pointer)*i); if (not isBadReadPtr(pExportNameNow,SizeOf(DWord))) then begin ExportName := PChar(pExportNameNow^+ DWord(DosHeader)); if (ExportName = pFunctionName) then {is it the export we search? Calculate the ordinal.} begin pExportOrdinalNow := Pointer(Integer(pFirstExportOrdinal)+SizeOf(Word)*i); if (not isBadReadPtr(pExportOrdinalNow,SizeOf(Word))) then iExportOrdinal := pExportOrdinalNow^; end; end; end; end else{no PChar, calculate the ordinal directly} iExportOrdinal := DWord(pFunctionName)-DWord(ExportDirectory^.Base);
if (iExportOrdinal < 0) or (iExportOrdinal > Integer(ExportDirectory^.NumberOfFunctions)) then Exit; {havent found the ordinal}
pExportAddr := Pointer(iExportOrdinal*4+Integer(pFirstExportAddress)); if (isBadReadPtr(pExportAddr,SizeOf(DWord))) then Exit;
{Is the Export outside the ExportSection? If not its NT spezific forwared function} if (pExportAddr^ < DWord(DataDirectory^.VirtualAddress)) or (pExportAddr^ > DWord(DataDirectory^.VirtualAddress+DataDirectory^.Size)) then begin if (pExportAddr^ <> 0) then {calculate export address} Result := Pointer(pExportAddr^+DWord(DosHeader)); end else begin {forwarded function (like kernel32.EnterCriticalSection -> NTDLL.RtlEnterCriticalSection)} ExportName := PChar(dwLibraryHandle+pExportAddr^); dwPosDot := Pos('.',ExportName); if (dwPosDot > 0) then begin dwNewModule := GetModuleHandle(PChar(Copy(ExportName,1,dwPosDot-1))); if (dwNewModule = 0) then dwNewModule := LoadLibrary(PChar(Copy(ExportName,1,dwPosDot-1))); if (dwNewModule <> 0) then result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName)))); end; end; end;