unit UnitWinUtils;

interface
uses
        Windows;

Type
        TDWA128=Array [1..128] of LongWord;
        TDWA256=Array [1..256] of LongWord;
        TDWA512=Array [1..512] of LongWord;
        TDWA1024=Array [1..1024] of LongWord;
        TDWA4096=array [1..4096] of LongWord;
        TDWA32768=array[1..32768] of LongWord;

function GetAllChildWnd(ChildWnd: HWND; lp: lParam):Boolean;stdcall;
function GetTextByHwnd(Const ChildWnd:LongWord):AnsiString;
function GetClassnameByHwnd(const h:HWND):AnsiString;
procedure GetAllOpenWindowsHwnd(var aProcesses:TDWA1024;var len:Integer);
function GetAllProcesses(var aProcesses:TDWA128;var len:Integer):Boolean;
function GetFileNameByPID(Const PID:DWORD;var FileName:AnsiString):Boolean;
function InstanceToWnd(targetpid: LongWord): LongWord;
function IsExeRunning(Const Exe:String):boolean;
function IncludeNull2String(s:String):String;
function GetPIDByHWND(const h1:Cardinal):Cardinal;
function HexToInt(h:AnsiString):Integer;
function IsWin64: boolean;
function GetWindowsVersion: String;
function BrowseForFolder(const browseTitle: string; const initialFolder: string = ''): string;
function GetProcessFilePathByPId( const dwProcessId:DWORD; var cstrPath:AnsiString ):boolean;
function GetBuildInfo: AnsiString;
procedure FileCopy(sf,tf:AnsiString);

var
        dwa4096:TDWA32768;
        elementCount:integer=0;


implementation
uses
        SysUtils,  shlobj,  PSAPI,Messages,Classes;


//--------------------由父窗体句柄获取其内的所有子窗体句柄-------passed---------
function GetAllChildWnd(ChildWnd: HWND; lp: lParam):Boolean;stdcall;
{ 在主程序中调用语法:EnumChildWindows(ParentWnd, @GetAllChildWnd, 1);}
begin
        if IsWindow(ChildWnd) then
        begin
                Inc(elementCount);
                if elementCount<=32768 then
                        dwa4096[elementCount]:=ChildWnd
                else
                begin
                        Result:=False;
                        Exit;
                end;
        end;
        Result := true;
        EnumChildWindows(ChildWnd, @GetAllChildWnd,1 );//递归枚举
end;

//-------------------------由窗体句柄获取窗体文字------------------passed-------
function GetTextByHwnd(Const ChildWnd:LongWord):AnsiString;
var
        ControlText:AnsiString;
begin
        SetLength(ControlText,128);
        GetWindowText(ChildWnd, @ControlText[1], 128);
        if GetWindowTextLength(ChildWnd) = 0 then
        begin
                if SendMessage(ChildWnd, WM_GETTEXT,Length(ControlText), LongWord(@ControlText[1]))>0 then
                        Result:=ControlText
                else
                        Result:='';
        end
        else
        begin
                if GetWindowTextLength(ChildWnd)>0 then
                        Result:=ControlText
                else
                        Result:='';
        end;
end;

//-----------------
function GetClassnameByHwnd(const h:HWND):AnsiString;
var
        buf:array [0..64] of AnsiChar;
begin
        GetClassName(h,@buf[0],64);
        Result:=IncludeNull2String(buf);
end;
//-----------------

//-----------获取当前已打开的所有顶级窗口的句柄---------------------passed------
procedure GetAllOpenWindowsHwnd(var aProcesses:TDWA1024;var len:Integer);
var
        hwnd:LongWord;
begin
        len:=0;
        hwnd := FindWindow(nil, nil); // 返回窗口的句柄
        while hwnd <> 0 do
        begin
//                if GetParent(hwnd) = 0 then // 说明是顶级窗口
                begin
                        aProcesses[len+1]:=hwnd;
                        Inc(len);
                end;
                hwnd := GetWindow(hwnd, GW_HWNDNEXT);
        end;
end;
//------------------------------------------------------------------------------

//-------------获取正在运行的进程列表数组,个数放len----------------passed-------
function GetAllProcesses(var aProcesses:TDWA128;var len:Integer):Boolean;
var
        cbNeeded:DWORD;
begin
        Result:=False;
        len:=0;
        if not EnumProcesses(@aProcesses[1],sizeof(aProcesses),cbNeeded) then
                Exit
        else
        begin
                len:=cbNeeded div sizeof(DWORD);
                Result:=True;
        end;
end;
//------------------------------------------------------------------------------

//----------------------根据窗体句柄,获取PID-----------------------------------
function GetPIDByHWND(const h1:Cardinal):Cardinal;
begin
        GetWindowThreadProcessId(h1, Result);
end;


//------------------------------------------------------------------------------

    function GetProcessFilePathByPId( const dwProcessId:DWORD; var cstrPath:AnsiString ):boolean;
    var
            hProcess:Cardinal;
            bSuccess:BOOL;
        szPath:array[1..255]of AnsiChar;
        hMod:HMODULE ;
        cbNeeded:DWORD;

    begin
            // 由于进程权限问题,有些进程是无法被OpenProcess的,如果将调用进程的权限
            // 提到“调试”权限,则可能可以打开更多的进程
        hProcess:=0;
    hProcess := OpenProcess( PROCESS_QUERY_INFORMATION or PROCESS_VM_READ ,FALSE, dwProcessId );
    bSuccess:=False;
        //repeat
                if ( 0 = hProcess ) then
                    // 打开句柄失败,比如进程为0的进程
                    exit;

                // 用于保存文件路径,扩大一位,是为了保证不会有溢出


                // 模块句柄
                hMod := 0;
                // 这个参数在这个函数中没用处,仅仅为了调用EnumProcessModules
                cbNeeded := 0;

                // 获取路径
                // 因为这个函数只是要获得进程的Exe路径,因为Exe路径正好在返回的数据的
                // 第一位,则不用去关心cbNeeded,hMod里即是Exe文件的句柄.
                // If this function is called from a 32-bit application running on WOW64,
                // it can only enumerate the modules of a 32-bit process.
                // If the process is a 64-bit process,
                // this function fails and the last error code is ERROR_PARTIAL_COPY (299).
                if  False=EnumProcessModules( hProcess, @hMod, sizeof( hMod ), cbNeeded )  then
                    exit;


                // 通过模块句柄,获取模块所在的文件路径,此处即为进程路径。
                // 传的Size为MAX_PATH,而不是MAX_PATH+1,是因为保证不会存在溢出问题
                if ( 0 = GetModuleFileNameEx( hProcess, hMod, @szPath[1], 255 ) )  then
                    exit;


                // 保存文件路径
                cstrPath := IncludeNull2String(szPath);//去掉了尾部多余的串

                // 查找成功了
                bSuccess := TRUE;
        //until false;

            // 释放句柄
        if ( 0 <> hProcess ) then
        begin
                CloseHandle( hProcess );
                hProcess := 0;
        end;

        result:=bSuccess;
    end;


//----------------------根据进程号查程序的路径、名字----------------------------
function GetFileNameByPID(Const PID:DWORD;var FileName:AnsiString):Boolean;
var
        hProcess:HWND;
        hMod:HMODULE;
        cbNeeded,dwRetValEx:DWORD;
        szProcessPath:Array [1..255] of AnsiChar;
begin
        Result:=False;
        FileName:='';
        hProcess:=OpenProcess( PROCESS_QUERY_INFORMATION or PROCESS_VM_READ , FALSE, PID);
        if hProcess =0  then
        begin
                //repeat
//                        if  EnumProcessModules( hProcess, @hMod, sizeof(hMod), cbNeeded)  then
//                        begin
                                //dwRetValEx := GetModuleFileNameEx( hProcess, hMod, @szProcessPath[1], Sizeof(szProcessPath));
                                dwRetValEx := GetModuleFileNameEx( hProcess, 0, @szProcessPath[1], Sizeof(szProcessPath));
                                if (dwRetValEx>0) then
                                begin
                                        FileName:=IncludeNull2String(szProcessPath);
                                        Result:=True;
                                end
                                else
                                        exit;
//                        end
//                        else
//                                exit;
                //until True;
                CloseHandle(hProcess);
        end
end;
//------------------------------------------------------------------------------

//-------------------判断某个程序是否正在运行----------------------------------
function IsExeRunning(Const Exe:AnsiString):boolean;
var
        hProcess:HWND;
        aProcesses:array [1..256] of DWORD;
        cbNeeded, cProcesses,{dwRetVal,}dwRetValEx:DWORD;
        i:integer;
        hMod:HMODULE;
        szProcessName,szProcessPath:String[255];
        tmp:AnsiString;
begin
        Result:=False;
        if not EnumProcesses(@aProcesses[1],sizeof(aProcesses),cbNeeded) then
                Exit;
        cProcesses:=cbNeeded div sizeof(DWORD);
        //数组中装的全是进程的ID。个数在cProcesses中。

        for i:= cProcesses downto 1 do
        begin
                hProcess:=OpenProcess( PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, aProcesses[i]);
                if hProcess <>0  then
                begin
                        if  EnumProcessModules( hProcess, @hMod, sizeof(hMod), cbNeeded)  then
                        begin
                                SetLength(szProcessName,255);
                                SetLength(szProcessPath,255);
                                //dwRetVal := GetModuleBaseName( hProcess, hMod, @szProcessName[1], Sizeof(szProcessName) );
                                dwRetValEx := GetModuleFileNameEx( hProcess, hMod, @szProcessPath[1], Sizeof(szProcessPath));
                                if (dwRetValEx>0) then
                                begin
                                        tmp:=UpperCase(IncludeNull2String(szProcessPath));
                                        if tmp=UpperCase(Exe) then
                                        begin
                                                Result:=True;
                                                Exit;
                                        end;
                                end
                        end
                end
        end;
end;
//------------------------------------------------------------------------------

//----------------------根据进程id查窗口句柄------------------------------------
function InstanceToWnd(targetpid: LongWord): LongWord;
var
        hwnd, pid, threadid: LongWord;
begin
        Result:=0;
        hwnd := FindWindow(nil, nil); // 返回窗口的句柄
        while hwnd <> 0 do
        begin
                if GetParent(hwnd) = 0 then // 指定子窗口的父窗口句柄
                begin
                        threadid := GetWindowThreadProcessId(hwnd, pid);
                        // 返回创建窗口的线程id,进程号存放在pid
                        if pid = targetpid then
                        begin
                                Result := hwnd;
                                break;
                        end;
                end;
                hwnd := GetWindow(hwnd, GW_HWNDNEXT);
        end;
end;
//------------------------------------------------------------------------------

//----------------------将包含NULL的串转换为String------------------------------
function IncludeNull2String(s:AnsiString):AnsiString;
var
        i:integer;
begin
        if s='' then
        begin
                Result:='';
                exit;
        end;
        SetLength(Result,Length(s));
        i:=1;
        While (s[i]<>#0)and(i<=Length(s)) do
        begin
                Result[i]:=s[i];
                Inc(i);
        end;
        SetLength(Result,i-1);
end;
//------------------------------------------------------------------------------

//---------将16进制串转换成10进制整数------------------------------------------
function HexToInt(h:AnsiString):Integer;
        function CharToInt(const c:AnsiChar):Byte;
        begin
                case c of
                        '0'..'9':Result:=Ord(c)-$30;
                        'a'..'f':Result:=Ord(c)-$57;
                        else
                                Result:=0;
                end;
        end;
var
        i,j:Byte;
begin
        h:=LowerCase(h);
        j:=Length(h);
        if j>8 then
                j:=8;
        Result:=0;
        for i:=1 to j do
                Result:=Result*16+CharToInt(h[i]);
end;
//-------------------------------------------------------------

// ----------------------判断是否在windows 64位系统下运行-----------------------
function IsWin64: boolean;
type
        LPFN_ISWOW64PROCESS = function(Hand: Hwnd; Isit: Pboolean)
          : boolean; stdcall;
var
        pIsWow64Process: LPFN_ISWOW64PROCESS;
        IsWow64: boolean;
begin
        result := false;
        @pIsWow64Process := GetProcAddress(GetModuleHandle('kernel32'),
          'IsWow64Process');
        if @pIsWow64Process = nil then
                exit;
        pIsWow64Process(GetCurrentProcess, @IsWow64);
        result := IsWow64;
end;

// ---------------------------读取操作系统版本----------------------------------
function GetWindowsVersion:AnsiString;
var
        AWin32Version: Extended;
        os:AnsiString;
begin
        os := 'Windows ';
        AWin32Version :=
          StrtoFloat(Format('%d.%d', [Win32MajorVersion, Win32MinorVersion]));
        if Win32Platform = VER_PLATFORM_WIN32s then
                result := os + '32'
        else if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
        begin
                if AWin32Version = 4.0 then
                        result := os + '95'
                else if AWin32Version = 4.1 then
                        result := os + '98'
                else if AWin32Version = 4.9 then
                        result := os + 'Me'
                else
                        result := os + '9x'
        end
        else if Win32Platform = VER_PLATFORM_WIN32_NT then
        begin
                if AWin32Version = 3.51 then
                        result := os + 'NT 3.51'
                else if AWin32Version = 4.0 then
                        result := os + 'NT 4.0'
                else if AWin32Version = 5.0 then
                        result := os + '2000'
                else if AWin32Version = 5.1 then
                        result := os + 'XP'
                else if AWin32Version = 5.2 then
                        result := os + '2003'
                else if AWin32Version = 6.0 then
                        result := os + 'Vista'
                else if AWin32Version = 6.1 then
                        result := os + '7'
                else
                        result := os;
        end
        else
                result := os + '??';
end;

var        lg_StartFolder:AnsiString;

function BrowseForFolderCallBack(Wnd: Hwnd; uMsg: UINT; lParam, lpData: lParam) : Integer stdcall;
begin
        if uMsg = BFFM_INITIALIZED then
                SendMessage(Wnd, BFFM_SETSELECTION, 1,
                  Integer(@lg_StartFolder[1]));
        result := 0;
end;

function BrowseForFolder(const browseTitle:AnsiString; const initialFolder:AnsiString = ''):AnsiString;
const
        BIF_NEWDIALOGSTYLE = $40;
var
        browse_info: TBrowseInfo;
        folder: array [0 .. MAX_PATH] of char;
        find_context: PItemIDList;
begin
        FillChar(browse_info, SizeOf(browse_info), #0);
        lg_StartFolder := initialFolder;
        browse_info.pszDisplayName := @folder[0];
        browse_info.lpszTitle := PChar(browseTitle);
        browse_info.ulFlags := BIF_RETURNONLYFSDIRS or BIF_NEWDIALOGSTYLE;
        if initialFolder <> '' then
                browse_info.lpfn := BrowseForFolderCallBack;

        find_context := SHBrowseForFolder(browse_info);
        if Assigned(find_context) then
        begin
                if SHGetPathFromIDList(find_context, folder) then
                        result := folder
                else
                        result := '';
                GlobalFreePtr(find_context);
        end
        else
                result := '';
end;
//------------------------获取版本号-----------------------
function GetBuildInfo: AnsiString;
var
        verinfosize : DWORD;
        verinfo : pointer;
        vervaluesize : dword;
        vervalue : pvsfixedfileinfo;
        dummy : dword;
        v1,v2,v3,v4 : word;
begin
        verinfosize := getfileversioninfosize(pchar(paramstr(0)),dummy);
        if verinfosize = 0 then
        begin
                dummy := getlasterror;
                result := '0.0.0.0';
        end;
        getmem(verinfo,verinfosize);
        getfileversioninfo(pchar(paramstr(0)),0,verinfosize,verinfo);
        verqueryvalue(verinfo,'\',pointer(vervalue),vervaluesize);
        with vervalue^ do
        begin
                v1 := dwfileversionms shr 16;
                v2 := dwfileversionms and $ffff;
                v3 := dwfileversionls shr 16;
                v4 := dwfileversionls and $ffff;
        end;
        result := inttostr(v1) + '.' + inttostr(v2) + '.' + inttostr(v3) + '.' + inttostr(v4);
        freemem(verinfo,verinfosize);
end;
//---------------------------------------------------------------------

//--------------复制文件-----------
procedure FileCopy(sf,tf:AnsiString);
var
        ms:TMemoryStream;
begin
        ms:=TMemoryStream.Create;
        ms.LoadFromFile(sf);
        ms.Position:=0;
        ms.SaveToFile(tf);
        ms.Free;
end;
//----------------------------------

end.
View Code

内存加载DLL

//从内存中加载DLL DELPHI版     
unit MemLibrary;  
interface  
uses  
Windows;  
  
function memLoadLibrary(pLib: Pointer): DWord;  
function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;  
function memFreeLibrary(dwHandle: DWord): Boolean;  
  
implementation  
procedure ChangeReloc(baseorgp, basedllp, relocp: pointer; size: cardinal);  
type  
    TRelocblock = record  
        vaddress: integer;  
        size: integer;  
    end;  
    PRelocblock = ^TRelocblock;  
var  
    myreloc: PRelocblock;  
    reloccount: integer;  
    startp: ^word;  
    i: cardinal;  
    p: ^cardinal;  
    dif: cardinal;  
begin  
    myreloc := relocp;  
    dif := cardinal(basedllp)-cardinal(baseorgp);  
    startp := pointer(cardinal(relocp)+8);  
    while myreloc^.vaddress <> 0 do  
    begin  
      reloccount := (myreloc^.size-8) div sizeof(word);  
      for i := 0 to reloccount-1 do  
      begin  
        if (startp^ xor $3000 < $1000) then  
        begin  
          p := pointer(myreloc^.vaddress+startp^ mod $3000+integer(basedllp));  
          p^ := p^+dif;  
        end;  
        startp := pointer(cardinal(startp)+sizeof(word));  
      end;  
      myreloc := pointer(startp);  
      startp := pointer(cardinal(startp)+8);  
    end;  
end;  
procedure CreateImportTable(dllbasep, importp: pointer); stdcall;  
type  
    timportblock = record  
          Characteristics: cardinal;  
          TimeDateStamp: cardinal;  
          ForwarderChain: cardinal;  
          Name: pchar;  
          FirstThunk: pointer;  
    end;  
    pimportblock = ^timportblock;  
var  
    myimport: pimportblock;  
    thunksread, thunkswrite: ^pointer;  
    dllname: pchar;  
    dllh: thandle;  
    old: cardinal;  
begin  
    myimport := importp;  
    while (myimport^.FirstThunk <> nil) and (myimport^.Name <> nil) do  
    begin  
      dllname := pointer(integer(dllbasep)+integer(myimport^.name));  
      dllh := LoadLibrary(dllname);  
      thunksread := pointer(integer(myimport^.FirstThunk)+integer(dllbasep));  
      thunkswrite := thunksread;  
      if integer(myimport^.TimeDateStamp) = -1 then  
        thunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));  
      while (thunksread^ <> nil) do  
      begin  
        if VirtualProtect(thunkswrite,4,PAGE_EXECUTE_READWRITE,old) then  
        begin  
          if (cardinal(thunksread^) and $80000000 <> 0) then  
          thunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) else  
          thunkswrite^ := GetProcAddress(dllh,pchar(integer(dllbasep)+integer(thunksread^)+2));  
          VirtualProtect(thunkswrite,4,old,old);  
        end;  
        inc(thunksread,1);  
        inc(thunkswrite,1);  
      end;  
      myimport := pointer(integer(myimport)+sizeof(timportblock));  
    end;  
end;  
  
function memLoadLibrary(pLib: Pointer): DWord;  
var  
DllMain    : function (dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;  
IDH        : PImageDosHeader;  
INH        : PImageNtHeaders;  
SEC        : PImageSectionHeader;  
dwSecCount : DWord;  
dwLen      : DWord;  
dwmemsize : DWord;  
i          : Integer;  
pAll       : Pointer;  
begin  
Result := 0;  
IDH := pLib;  
if isBadReadPtr(IDH, SizeOf(TImageDosHeader)) or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then  
    Exit;  
INH := pointer(cardinal(pLib)+cardinal(IDH^._lfanew));  
if isBadReadPtr(INH, SizeOf(TImageNtHeaders)) or (INH^.Signature <> IMAGE_NT_SIGNATURE) then  
    Exit;  
// if (pReserved <> nil) then   
//    dwLen := Length(pReserved)+1   
// else   
    dwLen := 0;  
SEC := Pointer(Integer(INH)+SizeOf(TImageNtHeaders));  
dwMemSize := INH^.OptionalHeader.SizeOfImage;  
if (dwMemSize = 0) then Exit;  
pAll := VirtualAlloc(nil,dwMemSize+dwLen,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);  
if (pAll = nil) then Exit;  
dwSecCount := INH^.FileHeader.NumberOfSections;  
CopyMemory(pAll,IDH,DWord(SEC)-DWord(IDH)+dwSecCount*SizeOf(TImageSectionHeader));  
// CopyMemory(Pointer(DWord(pAll) + dwMemSize),pReserved,dwLen-1);   
CopyMemory(Pointer(DWord(pAll) + dwMemSize),nil,dwLen-1);  
for i := 0 to dwSecCount-1 do  
begin  
    CopyMemory(Pointer(DWord(pAll)+SEC^.VirtualAddress),  
          Pointer(DWord(pLib)+DWord(SEC^.PointerToRawData)),  
          SEC^.SizeOfRawData);  
    SEC := Pointer(Integer(SEC)+SizeOf(TImageSectionHeader));  
end;  
if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then  
    ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase),  
          pAll,  
          Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),  
          INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);  
CreateImportTable(pAll, Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));  
@DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint+DWord(pAll));  
// if (INH^.OptionalHeader.AddressOfEntryPoint <> 0) and (bDllMain) then   
if INH^.OptionalHeader.AddressOfEntryPoint <> 0 then  
begin  
    try  
//      if (pReserved <> nil) then   
//        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)   
//      else   
        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,0);  
    except  
    end;  
end;  
Result := DWord(pAll);  
end;  
  
function memFreeLibrary(dwHandle: DWord): Boolean;  
var  
IDH: PImageDosHeader;  
INH: PImageNTHeaders;  
begin  
Result := false;  
if (dwHandle = 0) then  
    Exit;  
IDH := Pointer(dwHandle);  
if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then  
    Exit;  
INH := Pointer(DWord(IDH^._lfanew)+DWord(IDH));  
if (INH^.Signature <> IMAGE_NT_SIGNATURE) then  
    Exit;  
if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then  
    Result := True;  
end;  
  
function memGetProcAddress(dwLibHandle: 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;  
if pFunctionName = nil then Exit;  
DosHeader := Pointer(dwLibHandle);  
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;  
pFirstExportName := Pointer(DWord(ExportDirectory^.AddressOfNames)+DWord(DosHeader));  
pFirstExportOrdinal := Pointer(DWord(ExportDirectory^.AddressOfNameOrdinals)+DWord(DosHeader));  
pFirstExportAddress := Pointer(DWord(ExportDirectory^.AddressOfFunctions)+DWord(DosHeader));  
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(dwLibHandle+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 := GetProcAddress(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));  
    end;  
end;  
end;  
end.
View Code

 

posted on 2019-02-02 13:48  EEEEEEEEEEEEEEEEEEE  阅读(508)  评论(0编辑  收藏  举报