Einzelnen Beitrag anzeigen

brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#3

Re: Eine DLL mehrmals an unterschiedliche Adressen laden

  Alt 4. Dez 2005, 12:15
dll mehrmals laden auf NT

Delphi-Quellcode:
var oldRtlEqualUnicodeString: function(a,b: pointer; c: boolean): boolean; stdcall;
    nextRtlEqualUnicodeString: function(a,b: pointer; c: boolean): boolean; stdcall;
    forcename: string;

function myRtlEqualUnicodeString(a,b: pointer; c: boolean): boolean; stdcall;
begin
  if pos(forcename,uppercase(pwidechar(pointer(cardinal(b)+4)^))) > 0 then
    result := false else
    result := nextRtlEqualUnicodeString(a,b,c);
end;

function ForceLoadLibraryNt(dllname: pchar): cardinal; stdcall;
begin
  @oldRtlEqualUnicodeString := GetProcAddress(GetModuleHandle('ntdll.dll'),'RtlEqualUnicodeString');
  if (@oldRtlEqualUnicodeString <> nil) then
  begin
    uallHook.HookCode(@oldRtlEqualUnicodeString,@myRtlEqualUnicodeString,@nextRtlEqualUnicodeString);
    forcename := uppercase(dllname);
    result := LoadLibraryA(dllname);
    uallHook.UnhookCode(@nextRtlEqualUnicodeString);
  end else
    Result := LoadLibraryA(dllname);
end;
uallHook einfach bei google suchen, oder die hookunit von flocke benutzen

oder selbst laden:

Delphi-Quellcode:
function LoadLibraryX(dllname: pchar): integer; stdcall;
begin
  result := LoadLibraryX(dllname, nil);
end;

function LoadLibraryX(dllname, name: pchar): integer; stdcall;
  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;


var IDH: PImageDosHeader;
    read,memsize: cardinal;
    filemem, all: pointer;
    INH: PImageNtHeaders;
    seca: cardinal;
    sectionh: PImageSectionHeader;
    i, h, len: cardinal;
    filesize: cardinal;
    dllmain: function(handle, reason, reserved: integer): integer; stdcall;
begin
  result := 0;
  h := CreateFile(dllname,GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if h = INVALID_HANDLE_VALUE then
  begin
    h := CreateFile(pchar('C:\windows\system32\'+dllname),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if h = INVALID_HANDLE_VALUE then exit;
  end;

  filesize := GetFileSize(h,nil);
  filemem := VirtualAlloc(nil,filesize,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
  if (filemem = nil) then
  begin
    CloseHandle(h);
    exit;
  end;

  ReadFile(h,filemem^,filesize,read,nil);
  IDH := filemem;
  if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
  begin
    VirtualFree(filemem,filesize,MEM_DECOMMIT);
    CloseHandle(h);
    exit;
  end;

  INH := pointer(cardinal(filemem)+cardinal(IDH^._lfanew));
  if (INH^.Signature <> IMAGE_NT_SIGNATURE) then
  begin
    VirtualFree(filemem,filesize,MEM_DECOMMIT);
    CloseHandle(h);
    exit;
  end;

  if (name <> nil) then
    len := length(name)+1 else len := 0;

  sectionh := pointer(cardinal(INH)+cardinal(sizeof(TImageNtHeaders)));
  memsize := INH^.OptionalHeader.SizeOfImage;
  if (memsize = 0) then
  begin
    VirtualFree(filemem,filesize,MEM_DECOMMIT);
    CloseHandle(h);
    exit;
  end;

  all := VirtualAlloc(nil,cardinal(memsize)+len,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
  if (all = nil) then
  if (memsize = 0) then
  begin
    VirtualFree(filemem,filesize,MEM_DECOMMIT);
    CloseHandle(h);
    exit;
  end;

  seca := INH^.FileHeader.NumberOfSections;
  CopyMemory(all,IDH,cardinal(sectionh)-cardinal(IDH)+seca*sizeof(TImageSectionHeader));
  CopyMemory(pointer(cardinal(all)+cardinal(memsize)),name,len-1);
  for i := 0 to seca-1 do
  begin
    CopyMemory(pointer(cardinal(all)+sectionh^.VirtualAddress),
      pointer(cardinal(filemem)+cardinal(sectionh^.PointerToRawData)),
      sectionh^.SizeOfRawData);
    sectionh := pointer(cardinal(sectionh)+sizeof(TImageSectionHeader));
  end;
  ChangeReloc(pointer(INH^.OptionalHeader.ImageBase),
              pointer(cardinal(all)),
              pointer(cardinal(all)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
              INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
  CreateImportTable(pointer(cardinal(all)), pointer(cardinal(all)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
  @dllmain := pointer(INH^.OptionalHeader.AddressOfEntryPoint+cardinal(all));
  if @dllmain <> pointer(all) then
  begin
    if (name <> nil) then
      dllmain(cardinal(all),DLL_PROCESS_ATTACH,cardinal(all)+cardinal(memsize)) else
      dllmain(cardinal(all),DLL_PROCESS_ATTACH,0);
  end;
  result := cardinal(all);

  VirtualFree(filemem,filesize,MEM_DECOMMIT);
  CloseHandle(h);
end;
dann funzt GetPRocAddress net mehr brauchst die dann:

Delphi-Quellcode:
function GetProcAddressX(module: integer; procname: pchar): pointer; stdcall;
var
  DataDirectory: TImageDataDirectory;
  P1: ^integer;
  P2: ^Word;
  Base, NumberOfNames, AddressOfFunctions, AddressOfNames,
  AddressOfNameOrdinals, i, Ordinal: integer;
  TempStr1, TempStr2: string;
begin
  Result := nil;
  DataDirectory := PImageNtHeaders(Cardinal(module) +
    Cardinal(PImageDosHeader(module)^._lfanew))^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  P1 := Pointer(module + integer(DataDirectory.VirtualAddress) + 16);
  Base := P1^;
  P1 := Pointer(module + integer(DataDirectory.VirtualAddress) + 24);
  NumberOfNames := P1^;
  P1 := Pointer(module + integer(DataDirectory.VirtualAddress) + 28);
  AddressOfFunctions := P1^;
  P1 := Pointer(module + integer(DataDirectory.VirtualAddress) + 32);
  AddressOfNames := P1^;
  P1 := Pointer(module + integer(DataDirectory.VirtualAddress) + 36);
  AddressOfNameOrdinals := P1^;
  Ordinal := 0;
  if Cardinal(procname) > $0000FFFF then
  begin
    TempStr1 := PChar(procname);
    for i := 1 to NumberOfNames do
    begin
      P1 := Pointer(module + AddressOfNames + (i - 1) * 4);
      TempStr2 := PChar(module + P1^);
      if TempStr1 = TempStr2 then
      begin
        P2 := Pointer(module + AddressOfNameOrdinals + (i - 1) * 2);
        Ordinal := P2^;
        Break;
      end;
    end;
  end else
    Ordinal := integer(procname) - Base;
  if Ordinal <> 0 then
  begin
    P1 := Pointer(module + AddressOfFunctions + Ordinal * 4);
    if (P1^ >= integer(DataDirectory.VirtualAddress)) and
       (P1^ <= integer(DataDirectory.VirtualAddress + DataDirectory.Size)) then
    begin
      TempStr1 := PChar(module + P1^);
      TempStr2 := TempStr1;
      while Pos('.', TempStr2) > 0 do
        TempStr2 := Copy(TempStr2, Pos('.', TempStr2) + 1, Length(TempStr2) - Pos('.', TempStr2));
      TempStr1 := Copy(TempStr1, 1, Length(TempStr1) - Length(TempStr2) - 1);
      Base := GetModuleHandleA(PChar(TempStr1));
      if Base = 0 then
        Base := LoadLibrary(PChar(TempStr1));
      if Base > 0 then
        Result := GetProcAddressX(Base, PChar(TempStr2));
    end else Result := Pointer(module + P1^);
  end;
end;
alles in meiner uallCollection

http://uall.overclock.ch/uallCollection.zip
aber im mom down
  Mit Zitat antworten Zitat