Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Basisadresse der kernel32.dll unter Windows 9x (ohne API) (https://www.delphipraxis.net/26834-basisadresse-der-kernel32-dll-unter-windows-9x-ohne-api.html)

NicoDE 30. Jul 2004 02:46


Basisadresse der kernel32.dll unter Windows 9x (ohne API)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Es geht um die Ermittlung der Basisadresse der kernel32.dll ohne Verwendung die Win32 API. Unter Windows NT x86/x64 kenne ich etliche Möglichkeiten.
Nach langer Suche bin ich zufällig auf ein paar Zeilen gestossen, die zwar unter Windows 98 SE funktionieren - aber ich weiß weder warum es funktioniert, noch wie es mit den anderen Versionen von Win9x aussieht.

Kurz, ich suche entweder nach einer Erklärung oder nach Alternativen...
Delphi-Quellcode:
@@x:   { Windows 9x - FIXME }
        mov    eax, [eax+$34] { PDB.HeapHandle }
        lea    eax, [eax+$7c] { ???            }
        mov    eax, [eax+$3c] { ???            }
end;
Ein Test-Projekt ist angehängt und enthält bereits ein kompilierte Programm zum Testen.
(sollte mit allen Delphi-Versionen für Win32 kompilierbar sein)


Gruss Nico

NicoDE 31. Jul 2004 00:49

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Nach einigen Tests hat sich herausgestellt, dass o.g. Code nicht unter allen Win9x-Varianten funktioniert.

Der Standard SEH-Lookup sieht sicherer aus (Win9x/WinNT/Wine):
Delphi-Quellcode:
program k32base;

uses
  Windows;

{$R *.res}

const
  IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;
  {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

////////////////////////////////////////////////////////////////////////////////
//
//  GetKernel32Base
//
//  Returns base address of the kernel32.dll by walking the SEH handler chain.
//  Assumes:
//    a) Last record is ThreadStartup's exception handler inside kernel32.dll.
//    b) Images loaded on 64KB boundary (TSystemInfo.dwAllocationGranularity).
//
//  (code is optimized for minimal code size)
//

function GetKernel32Base: Pointer; assembler;
type
  PExceptionRegistrationRecord = ^TExceptionRegistrationRecord;
  TExceptionRegistrationRecord = record
    Next  : PExceptionRegistrationRecord;
    Handler: TFarProc;
  end;
  PNtTib = ^TNtTib;
  TNtTib = record
    ExceptionList      : PExceptionRegistrationRecord;
    StackBase          : Pointer;
    StackLimit         : Pointer;
    SubSystemTib       : Pointer;
    case Integer of
      1: (Version      : DWORD);
      0: (FiberData    : Pointer;
    ArbitraryUserPointer: Pointer;
    Self               : PNtTib);
  end;
asm
        xor    eax, eax
        mov    ecx, fs:[eax].TNtTib.ExceptionList
@@loop: { Loop until 0/-1 }
        jecxz  @@last
        mov    eax, [ecx].TExceptionRegistrationRecord.Handler
        mov    ecx, [ecx].TExceptionRegistrationRecord.Next
        inc    ecx
        jecxz  @@last
        dec    ecx
        jmp    @@loop
@@last: { Align and check }
        dec    ecx
        shl    ecx, 10h
        and    eax, ecx
        jz     @@exit
@@down: { Search downward }
        add    eax, ecx
        cmp    [eax].TImageDosHeader.e_magic, IMAGE_DOS_SIGNATURE
        jne    @@down
        movzx  edx, word ptr [eax].TImageDosHeader._lfanew
        cmp    [eax+edx].TImageNtHeaders.Signature, IMAGE_NT_SIGNATURE
        jne    @@down
@@exit: { exit: 30h bytes }
end;

////////////////////////////////////////////////////////////////////////////////

function HModToHex(Module: HMODULE; Digits: Integer): string;
const
  Digi: array [0..15] of Char = '0123456789ABCDEF';
var
  Loop: Byte;
begin
  SetLength(Result, Digits);
  for Loop := Digits downto 1 do
  begin
    Result[Loop] := Digi[Byte(Module) and $0F];
    Module := Module shr $04;
  end;
end;

var
  HKernel32: HMODULE;
  Filename: array [0..MAX_PATH] of Char;
begin
  HKernel32 := HMODULE(GetKernel32Base);
  GetModuleFilename(HKernel32, Filename, MAX_PATH);
  MessageBox(0, Filename, PChar(HModToHex(HKernel32, 8)), MB_OK);
end.

Luckie 31. Jul 2004 01:16

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Wozu braucht man die Basisadresse der kernel32.dll? :gruebel:

NicoDE 31. Jul 2004 02:10

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Zitat:

Zitat von Luckie
Wozu braucht man die Basisadresse der kernel32.dll? :gruebel:

Ich brauche relozierbaren Code für einen Remote-Thread. Da kann ich nicht mit Importen arbeiten.

dizzy 31. Jul 2004 04:14

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Zitat:

Zitat von NicoDE
Ich brauche relozierbaren Code für einen Remote-Thread. Da kann ich nicht mit Importen arbeiten.

...und wofür braucht man das? :gruebel:

(Böhmische Dörfer tun sich bei mir bei deinen Beiträgen des öfteren auf *g*)

NicoDE 31. Jul 2004 06:04

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Zitat:

Zitat von dizzy
...und wofür braucht man das? :gruebel:

Da der Code nichts ausserhalb der Funktion referenziert, kann er an eine beliebige Speicheradresse kopiert werden, ohne verändert werden zu müssen. Ich weiss vorher nicht an welcher Adresse ich Speicher reservieren kann und will mir die Arbeit mit der Relozierung von Code sparen.
(die eigentliche Funktion ist 'etwas' länger und importiert anhand der Basisadresse API-Funktionen - das oben ist nur zum Testen :))


Gruss Nico

<close>

NicoDE 1. Aug 2004 21:30

Re: Basisadresse der kernel32.dll unter Windows 9x (ohne API
 
Nur falls jemand auf die Idee kommen sollte die im oben angehängten Testprojekt enthaltene GetObsfucatorPid() zu verwenden,
der sollte besser folgenden Code verwenden:
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
//
//  GetObsfucator
//
//  Returns the value of kernel32.dwObsfucator on Consumer Windows (win9x).
//
//  Note that this version does *NOT* read kernel32 memory (as often seen).
//  Therefore, it can be called without the risk of raising any exceptions.
//  Furthermore, the function validates if the calculated value works, and
//  returns 0 if the Obsfucator isn't working (not Win9x | no obfuscation).
//

function GetObsfucator: DWORD;
{$IFDEF WIN32}
asm
        {                                                                }
        { Wellknown, methods to get the 'Obsfucator':                   }
        {                                                                }
        {   'Obsfucator' = Pid xor [TEB.PDB]                            }
        {   'Obsfucator' = Tid xor ( [TEB.Self] - TDB.TEB )             }
        {                                                                }
        { Therefore the TDB's offset from the TEB is:                   }
        {                                                                }
        {   -TDB.TEB = ( Tid xor Pid xor [TEB.PDB] ) - TEB.Self         }
        {                                                                }
        { If the offset is neither -8h (new Win9x) nor -10h (old Win9x), }
        { (the offset has changed through changes in the object header) }
        { then the current system isn't Win9x or obfuscation isn't used. }
        {                                                                }
        call   GetCurrentThreadId
        push   eax
        call   GetCurrentProcessId
        xor    edx, edx
        xor    eax, fs:[edx + 30h] { [TEB.PDB] }
        pop    ecx
        xor    ecx, eax
        sub    ecx, fs:[edx + 18h] { [TEB.Self] }
        add    ecx, 08h
        jecxz  @@done
        add    ecx, 08h
        jecxz  @@done
        xor    eax, eax
@@done:
end;
{$ELSE}
begin
  Result := 0;
end;
{$ENDIF}
Gruss Nico


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz