So I’ve actually been changing the prototypes around for the callback proc to see what would work
[in] LONG_PTR lParam
I’ve tried many combinations as a prototype
clarioncallback(long,long,long),bool,Raw,Pascal !Cant use Raw with a clarion proc
clarioncallback(long,long,long),bool,Raw,C !Cant use Raw with a clarion proc
clarioncallback(long,ulong,long),bool !ulong works with other api’s using makeintresource
clarioncallback(long,long),bool !not passing the hmodule
So the problem I keep seeing here is the address in lptype (2nd param) is moved to the hmodule param and the address in lParam (3rd param) is moved to the 2nd param.
I’ve tried sending null aka zero as the hmodule to enumerate the program calling these api’s, I’ve tried loadlibrary the same running program, and loadlibrary a different exe thats not running, and in those cases ie where hmodule is not null, the address in hmodule appears at the procedure call and then start the stack popping bit in assembler and the hmodule address dissappears and lptype becomes hmodule and lparam becomes lptype.
This is weird, I’ve never seen this happen like this before, but where I have the ulong in the prototype, ulong works with other api’s that take a long pointer to a cstring or const cstring and also takes a ulong.
Now for that trick to work, I have two api protptypes in the module section.
LoadIconA function (winuser.h) - Win32 apps | Microsoft Docs
LoadIconA uses lpcstr and MakeIntResource so I’ve defined to prototypes in the module(‘win32’) section
so the code uses procedure overloading for the windows api’s and this works well.
Same for LoadImageA as it also uses MakeIntResource
LoadImageA function (winuser.h) - Win32 apps | Microsoft Docs
Now whilst its not a prototype being used as a callback proc, I do have other callbacks working.
For example I have the DLLGetVersion callback working just fine eg.
Loc:lpPRocName = 'DllGetVersion'
Loc:DllGetVersionAddress = IS_GetProcAddress(self.vLibraryAddressShell32,Lov:lpProcName)
self.vDllVersionInfo2.DllVersionInfo.cbSize = Size(self.vDllVersionInfo2)
Loc:DllVersionInfo2Address = Address(self.vDllVersionInfo2)
Loc:hResult = self.DllGetVersionProc(Loc:DllVersionInfo2Address)
IF Loc:hResult = 0 !S_OK
self.vDllVersionMajor = self.vDllVersionInfo2.DllVersionInfo.dwMajorVersion
NotifyIcon.DllGetVersionProc Procedure(long pDllVersionInfo2Address)
but the parameters returned in resourcetype shunt left once the assembler for the callback starts.
So with a clarion app, the first resource type returned is 1492344d/16c578h which leads to the David A Bayliss dump aka DABDUMP. (Now thats interesting seeing what identifier appears online! in much the same way searching for anyscreen on shodan.io throws up lots of links ), but when looking at the mappings of the stack registers to the parameter prototypes what happens is:
EAX=resource address eg Address to DABDUMP
ECX=7h (first 64k addresses in windows are unusable)
EBP=address(self.enumerateTypesA) parent class method calling this callback procedure
ESP=? Its before the warning This program cannot be run in DOS mode.
EIP=address(self.EnumerateResourceTypeProcA) ie the address of the callback
Then when I step into the call back procedure ie first line of any local vars
EAX resource address changes to zero, losing the address in effect.
EBX becomes address stored in the phmodule (1st param in callback) when it should be lpType
ESI=pointer to phmodule (1st param)
So the address I would expect to see in lpType (2nd param) shifts to the hmodule (1stparm) and lParam (3rd param) shifts to the lpType 2nd param and hmodule (1st param) if populated shifts to the lParam (3rd param).
Its really weird, but another oddity which I dont know if its connected, is I have separate method in this class to get the hmodule, When it does, the handle is stored in a classwide (global var) which resets to zero when I call the method that calls the callback. So now using loadlibrary to look up the hmodule in the method that calls the callback as the filename also stored in a claswide variable is not reset.
Its weird, but maybe I spent too much time on this yesterday?
I should add the same happens with the parameters for enumResourceNamesA api which has 4 parameters in the callback.