Memory Search Function - Help please? ^^
A friend and i have being using/making/coding memory loaders/patchers in C++
For an interesting challenge we decided to try make a new lib using Delphi.
Now we could do the basic memory editing to fixed pointer addresses fairly easily but i did find Dwar's tutorials very very helpful in making sure what we did was correct using Delphi.
So now on to my question / issue - as part of our patcher lib we wanted a memory search function, something to match byte patterns with. In the end I ported the Boyer-Moore-Horspool method function that my friend wrote up in C++ over to Delphi.
Now it compiles and "seems" to work, but we know for a fact that it returns the wrong pointer address to the bytes that we want to match and edit. So somewhere in there it's not calculating the correct pointer.
I was hoping Dwar could see whats wrong with our function or suggest a better way of doing this in Delphi :wink:
Im sure this would benefit others as well if you can help us out!
Here's the ported function
PHP Code:
Function SearchMemory(SearchDLL: hModule; wildcard: Byte; searchCode: Array of Byte; size: Integer) : Pointer;
Const
UCHAR_MAX = 255;
Var
scan,lastByte,defaultSkip,pID, searchEnd : Cardinal;
skipLength : ARRAY of Integer;
dllInfo : TModuleInfo;
p : pointer;
pbCurrent: PByte;
b: Byte;
begin
//WriteLog('Hai loop');
//The first loop builds the skip length for characters that aren't in the searched "string"
lastByte := size - 1;
while searchCode[lastByte] = wildcard do
Dec(lastByte);
defaultSkip := lastByte;
//WriteLog('Second loop');
//The second one builds the skip length for the characters in the string
scan := 0;
for scan:= 0 to lastByte do
begin
if searchCode[scan] = wildcard then defaultSkip := lastByte - scan;
end;
if defaultSkip > 1 then defaultSkip := defaultSkip - 1;
//WriteLog('Skiplen loop');
//Is just setting the default skip length
SetLength(skipLength, UCHAR_MAX);
for scan:=0 to UCHAR_MAX do
skipLength[scan] := defaultSkip;
//WriteLog('Third loop');
//Third loop searches for the string, skipping bytes based on the skip length
for scan:= 0 to lastByte do
begin
if searchCode[scan] <> wildcard then
begin
skipLength[searchCode[scan]] := lastByte - scan;
end;
end;
pID := GetCurrentProcessID;
GetModuleInformation(pID, SearchDLL, @dllInfo, sizeof(dllInfo));
p := dllInfo.lpBaseOfDll;
searchEnd := Cardinal(dllInfo.lpBaseOfDll) + dllInfo.SizeOfImage;
searchEnd := searchEnd - (lastByte + 1);
//WriteLog(Format('Checking addr: %p, SearchEnd: %08X', [p, searchEnd]));
while Cardinal(p) <= searchEnd do
begin
//WriteLog(Format('Checking addr: %p', [p]));
pbCurrent := PByte(Cardinal(p) + lastByte);
while ((searchCode[scan] = wildcard) or (pbCurrent^ = searchCode[scan])) do
begin
if Cardinal(pbCurrent) = Cardinal(p) then
begin
result := p;
Exit;
end
else Dec(pbCurrent);
end;
Move(b, Pointer(Cardinal(p) + lastByte)^, 1); // Wtf how would you do this. Hmm
p := Pointer(Cardinal(p) + skipLength[b]);
end;
result:= 0;
end;
Link to post to a working version of function: [Only registered and activated users can see links. Click Here To Register...]