Exetools

Exetools (https://forum.exetools.com/index.php)
-   Source Code (https://forum.exetools.com/forumdisplay.php?f=46)
-   -   [Delphi] Search Memory (https://forum.exetools.com/showthread.php?t=19248)

phroyt 07-01-2019 01:24

[Delphi] Search Memory
 
Hi,

Some time ago I found a piece of code to SearchBytes.
After a little I come out with this.

Code:

//XE10 Compatible

uses
  System.SysUtils,
  System.Classes,
  Winapi.PsApi,
  Winapi.Windows;

Function SearchMemory(Module: hModule; wildcard: Byte; searchCode: Array of Byte; size: Integer; Offset: Cardinal = 0) : Pointer;

Implementation

//Search Memory
Function SearchMemory(Module: hModule; wildcard: Byte; searchCode: Array of Byte; size: Integer; Offset: Cardinal = 0) : Pointer;
Const
  UCHAR_MAX = 255;
Var
  scan,lastByte,defaultSkip, searchEnd,searchSuccess : NativeUInt;
  skipLength : ARRAY of Integer;
  dllInfo : TModuleInfo;
  p : pointer;
  OldProtect: DWORD;
begin

  searchSuccess := 0;
  lastByte := size - 1;
  result := nil;

  while searchCode[lastByte] = wildcard do
    Dec(lastByte);

  defaultSkip := lastByte;

  for scan:= 0 to lastByte - 1 do
  begin
    if searchCode[scan] = wildcard then
      defaultSkip := lastByte - scan;
  end;

  if defaultSkip > 1 then
    defaultSkip := defaultSkip - 1;

  //Is just setting the default skip length
  SetLength(skipLength, UCHAR_MAX);
  for scan:=0 to UCHAR_MAX do
    skipLength[scan] := defaultSkip;

  for scan := 0 to lastByte-1 do
    if searchCode[scan] <> wildcard then
      begin
        skipLength[searchCode[scan]] := lastByte - scan;
      end;

  if GetModuleInformation(GetCurrentProcess, Module, @dllInfo, sizeof(dllInfo)) then
    begin

      p := dllInfo.lpBaseOfDll;


      try

        searchEnd := Cardinal(dllInfo.lpBaseOfDll) + dllInfo.SizeOfImage;
        searchEnd := searchEnd - (lastByte + 1);

        if ((Cardinal(p)+offset) <= searchEnd) then
          p := Pointer(Cardinal(p)+offset);


        //FM: remove the write protect on Code Segment
        VirtualProtect(p, searchEnd, PAGE_EXECUTE_READWRITE, OldProtect);

        while Cardinal(p) <= searchEnd do
          begin
            scan := lastByte;

            while ((searchCode[scan] = wildcard) or (PByte(Cardinal(p)+scan)^ = searchCode[scan])) do
            begin
              if scan = 0 then
              begin
                Result := P;
                Inc(searchSuccess);
                Break;
              end;
              scan := scan-1;
            end;

            if ( searchSuccess <> 0 ) then
              break;

            p := Pointer(NativeInt(p)+skipLength[PByte(NativeUInt(p)+lastByte)^]);
          end;

        if ( searchSuccess = 0 ) then
          result := nil;

        if ( searchSuccess > 1 ) then
          result := nil;
      finally
        VirtualProtect(P, searchEnd, OldProtect, @OldProtect);
      end;
    end;
end;

Even without writing anything to Module memory, sometimes I got a wrong Byte value. Changing the protection solved this.


Any thoughts to improve?


Sample use:


Code:

const
//SFNTQueryFeature
Const SFNTQueryFeature_SIG :  Array [0..15] of Byte = ($55, $8B, $EC, $83, $EC,
                          $24, $C7, $45, $DC, $02, $00, $00, $00, $51, $31, $C9);

var
  base: hModule;
  proc1,
  proc2: Pointer;
  offset: Cardinal;

begin

  base := GetModuleHandle(nil);

  proc1 := SearchMemory(base, $00, SFNTGetLicense_SIG, length(SFNTGetLicense_SIG));

  if (proc1 <> nil) then
    offset := Cardinal(proc1)+1 - base;
 
  proc2 := SearchMemory(base, $00, SFNTGetLicense_SIG, length(SFNTGetLicense_SIG), offset);



All times are GMT +8. The time now is 18:30.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX