Em, one more question: if you write app in C++, if you already have a working function, so why are you trying to port piece of code into delphi?
Em, one more question: if you write app in C++, if you already have a working function, so why are you trying to port piece of code into delphi?
Please, post your questions on forum, not by PM or mail
I spend my time, so please pay a little bit of your time to keep world in equilibrium
I used Delphi for a number of years, i would say i am better at delphi than C++
Recently my friend started using delphi and liked the language, so we thought it would be an interesting project to create a new patching lib using delphi instead. We didn't know what method to try and use to search the apps memory for an array of bytes like we would do in C++ for patches so i decided since the function in C++ worked i would try to port it to delphi and see if it would work for us.
As you can see I've failed, which is why since i found your tuts etc very informative i would ask here for your advice.
I'm trying to analyze it with Olly atm, I'll tell you what i can.
Currently it's getting so far and crashing the game it's loaded into (that's not good huh?).
Edit:
It's loaded pretty early, and it crashes immediately so i can't catch much in Olly.
Probably need a better break point.
I might try using the function in a Delphi exe project rather than a DLL and see what i can get from the IDE debugger...
It's late where i live, i'll try this tomorrow.
Appreciate the help Dwar!
Last edited by RiiStar; 2011-09-26 at 10:27 AM.
Ok. You can examine CheatEngine source, you will find a lot of interesting things.
In Olly, set debug options to break on new module (dll). Another quick method to stop debugger: make a call of MessageBox just before calling search function in your code, like
[code[call MessageBoxA
call <find value>[/code]
then BP on MessageBoxA in user32. After that, you can step by step trace your <find value> func
Please, post your questions on forum, not by PM or mail
I spend my time, so please pay a little bit of your time to keep world in equilibrium
Here's the original C++ function
PHP Code:
// http://en.wikipedia.org/wiki/Boyer-Moore-Horspool_algorithm
LPBYTE PatchSearch(HMODULE hModule, LPBYTE searchCode, int size, BYTE wildcard) {
size_t skipLength[UCHAR_MAX + 1];
int scan;
int lastByte = size - 1;
while(searchCode[lastByte] == wildcard)
lastByte--;
int defaultSkip = lastByte;
for(scan = 0; scan < lastByte; scan++) {
if(searchCode[scan] == wildcard) {
defaultSkip = lastByte - scan;
}
}
if(defaultSkip > 1) defaultSkip--;
for(scan = 0; scan < (UCHAR_MAX + 1); scan++)
skipLength[scan] = defaultSkip;
for(scan = 0; scan < lastByte; scan++) {
if(searchCode[scan] != wildcard) {
skipLength[searchCode[scan]] = lastByte - scan;
}
}
MODULEINFO dllInfo;
GetModuleInformation(GetCurrentProcess(), hModule, &dllInfo, sizeof(dllInfo));
LPBYTE p = (LPBYTE)dllInfo.lpBaseOfDll;
LPBYTE searchEnd = (LPBYTE)dllInfo.lpBaseOfDll + dllInfo.SizeOfImage;
searchEnd -= lastByte + 1;
while(p <= searchEnd) {
scan = lastByte;
while(searchCode[scan] == wildcard || p[scan] == searchCode[scan]) {
if(scan == 0) return p;
scan--;
}
p += skipLength[p[lastByte]];
}
return NULL;
}
that code looks basic.
You just have to figure out what everything means.. and find same thing in delphi like..
UCHAR_MAX
you google this you find
#define UCHAR_MAX 255
so this line mean
size_t skipLength[255 + 1];
or
size_t skipLength[256];
then size_t could mean anything
then you look at this
skipLength[scan] = defaultSkip;
and then you see
int defaultSkip = lastByte;
so skipLength is int
int skipLength[256];
maybe problems with parameters too
like
LPBYTE searchCode
well.. LPBYTE is declared as
typedef byte* LPBYTE
then what is byte?
typedef unsigned char BYTE;
okay now you know BYTE means unsigned char.. and LPBYTE means unsigned byte pointer..
so we know
LPBYTE searchCode
is.. byte array of unsigned bytes..
byte[] searchCode //<- in C#.
we also now know..
BYTE wildcard is also unsigned char so,..
byte wildcard //<- in C#.
HMODULE hModule
typedef HINSTANCE HMODULE; //<-- see HMODULE mean HINSTANCE
typedef HANDLE HINSTANCE; //<- HINSTANCE mean HANDLE
typedef PVOID HANDLE; //<- HANDLE is PVOID
typedef void* PVOID; //<- PVOID is VOID * [void pointer]
Void pointer is a pointer that is pointing to any type of unknown data.. then you can cast it to anything you wish char,int,float, you must know what data you put in kind of pointer or else you might forget about it.
This doesn't explain much, but.
HMODULE and HINSTANCE = Base Address of DLL or EXE which is loaded in memory, it is a unsigned long pointer.
I think Delphi supports HMODULE and HINSTANCE.. or either one should work, if not it is just unsigned long pointer.. or from googling same as ^LongWord
Other than that nothing really to hard about that example.
Have to figure out how API works in delphi for GetModuleInformation it should be found in Win32API, I think this can be googled easily with "WIN32API GetModuleInformation Delphi" found example something like this
Okay it seems.. hModule should be in Delphi THandle
Lol delphi looks horrible something like this.. I don't know if this will work..
then pretty muchCode:var dllInfo: TModuleInfo; begin GetModuleInformation(GetCurrentProcess, hModule, @dllInfo, SizeOf(dllInfo)); end;
LPBYTE p = (LPBYTE)dllInfo.lpBaseOfDll;
LPBYTE searchEnd = (LPBYTE)dllInfo.lpBaseOfDll + dllInfo.SizeOfImage;
LPBYTE p is pointer to byte array which starts at dllInfo.lpBaseOfDll.
searchEnd is p which is where base address starts for dll and plus sizeOfImage of dll which gets the address where base address ends.
Hope it helps.. probably Dwar will do it all for you anyways.
If you look at the original post, you will see i did try to do much of what you said in figuring out the the delphi equivalent.
I've done something wrong in there, i think it's the pointer arithmetic and perhaps BaseDLL / size of image.
I'll review what i wrote and look at your suggestions.
Btw pkedpker... who are you from SubSpace??
Shit completely missed the first topic.. yeah this delphi is really alien to me.. You don't know me on subspace.. I used to play with Qualified as Pokemon 2001 other then that I didn't really know anyone else other then that asian girl Jaclyan.
I recently was trying to make a automatic continuum bot that flys around TW/EG (big zones) and kills like normal player from boredom.. I got very far.. managed to port the whole encryption from Continuum v0.40.. but these packets follow so much formats.. I did research some called Clusters some called Big Chunks/Small Chunks/Reliable Packets.. really pissed me off and I gave up on the project :p. I attempted to ignore these stupid packets.. only the ones i need.. like player positions and death packets etc.. but then I tried send packets back to server.. nothing happened.. Very strange never had this type of problem with any game.. But then again Continuum uses UDP protocol for all packet stuff.. maybe I did something wrong ehh.. I quit like you well..
But Continuum does give you this good feeling.. people shit talk and shit on you all day.. then you win.. and just leave to piss people off good feeling..
Also the feeling you can only get from subspace you get team killed.. then you play it cool.. and when the guy who team killed you least expects it.. kill him , he rages in private chat.. noob learn to play reported.. LOL. Then those people who really take the game seriously as ****, training everyday to hit invisible ships lol to learn shots and shit damn those people are committed.
Well I know no delphi sorry cannot help there.. but I tried to peice some code together might not even compile.
Delphi
Inc(p, skipLength[Pointer(Cardinal(p) + lastByte)^]);
As for this code
p += skipLength[p[lastByte]];
Last edited by pkedpker; 2011-09-27 at 01:15 AM.
I look into that code after work (2nd day working for a new Web design company) as it's 1:30pm here.
And i remember your username from Continuum, did you make a couple of maps also back in the day?
Don't count on it compiling, I just pieced together some text from your source code.. not even understanding like what is Cardinal or how arrays work in Delphi.
@SS
Yeah I made a few maps for tw.. forgot which meh not important non ever got popular.. and who cares really lol.
Good job man webdesign you must be very good artist.
Artist no, i am more coder than designer...
One benefit of being Trenchwars's head web developer for a time while i was staff i suppose.
Update:
So after a bit of a coding session and bouncing ideas off people, i might have got the original function i posted working.
Still need to debug some more and do some sanity checks on the pointer and bytes found at that address for patching, but hey it doesn't crash now and looks like it's getting the correct pointer address!
Still going to look at memory mapping as it will more than likely be faster and more efficient.
Last edited by RiiStar; 2011-09-29 at 08:25 PM. Reason: Update to what im doing without double posting...