I like to code for small code, so I maek an enum like this:
o0 = 0
ExitProcess = o0+0
GetCommandLine = o0+4
GetLastError = o0+8
GetModuleHandle = o0+12
o1 = o0+(4*4)
Direct3DCreate9 = o1+0
.D3D = o1+0
o2 = o1+(1*4)
CreateWindow = o2+0
RegisterClass = o2+4
ShowWindow = o2+8
UpdateWindow = o2+12
GetMessage = o2+16
TranslateMessage = o2+20
DispatchMessage = o2+24
PostQuitMessage = o2+28
DefWindowProc = o2+32
LoadIcon = o2+36
LoadCursor = o2+40
o3 = o2+(11*4)
LoadApi = o3+0
Then I can shorten most calls to 3 byte insteed of 5 or 6: As long as I keep the range in -7fh to 7fh.
mov ebp,offset FUNC0 ;use ebp as a pointer to my enum table
mov edi,offset DATA0 uuse edi as a pointer to my data table
eMSG = eWINC+(-7*4)
hwnd = oMSG-28
message = oMSG-24
wParam = oMSG-20
lParam = oMSG-16
time = oMSG-12
x = oMSG-8
y = oMSG-4
oMSG = -52;oWINC-(12*4)
eWINC = -48
cdSize = oWINC-48
style = oWINC-44
lpfnWndProc = oWINC-40
cbClsExtra = oWINC-36
cbWbdExtra = oWINC-32
hInstance = oWINC-28
hIcon = oWINC-24
hCursor = oWINC-20
hbrBackground = oWINC-16
lpszMenuName = oWINC-12
lpszClassName = oWINC-8
hIconSm = oWINC-4
oWINC = 0
eMSG = eWINC+(-7*4)
hwnd = oMSG-28
message = oMSG-24
wParam = oMSG-20
lParam = oMSG-16
time = oMSG-12
x = oMSG-8
y = oMSG-4
oMSG = -52;oWINC-(12*4)
eWINC = -48
cdSize = oWINC-48
style = oWINC-44
lpfnWndProc = oWINC-40
cbClsExtra = oWINC-36
cbWbdExtra = oWINC-32
hInstance = oWINC-28
hIcon = oWINC-24
hCursor = oWINC-20
hbrBackground = oWINC-16
lpszMenuName = oWINC-12
lpszClassName = oWINC-8
hIconSm = oWINC-4
oWINC = 0
invoke FP@48 ptr[ebx]+CreateWindow,esi,eax,[edi][WinClass.lpszClassName],00CF0000h,ecx,ecx,ecx,ecx,esi,esi,[edi][WinClass.hInstance],esi
00401096 56 push esi
00401097 FF 77 14 push dword ptr [edi+14h]
0040109A 56 push esi
0040109B 56 push esi
0040109C 51 push ecx
0040109D 51 push ecx
0040109E 51 push ecx
0040109F 51 push ecx
004010A0 68 00 00 CF 00 push 0CF0000h
004010A5 FF 77 28 push dword ptr [edi+28h]
004010A8 50 push eax
004010A9 56 push esi
004010AA FF 53 14 call dword ptr [ebx+14h]
Any macro or simplification?
Thanks.
If you do "assume edi:ptr WINDOWCLASS" then you can do "[edi].lpszClassName" without the need for the struct element offsets (assuming you're including windows.inc; otherwise define the structures as normal.) Don't forget to use "assume edi:nothing" when you finish with edi as that pointer, otherwise you'll get warnings.
I suppose you could define your own function-table-struct along the same lines.
P.S. ExitProcess takes one parameter, not zero :P
That's a = sign, only numeric equates. What that means is:
calll [ebp]+Exitprocess = call [ebp+0]
What I'm looking for is a macro that does not generate code but an offset table with hopefully easier insertion than:
o1 = o0+(4*4) size of each member of the address table (4 bytes)*4 api names in the previous table = start of next table
Direct3DCreate9 = o1+0 so 4*4+0 = 16 = Direct3DCreate9
The extra work is so I can add a new api in the middle of a list without having to change the offsets of the whole list. And makes is harder to accidentally use a duplicate offset value that could lead to a hard to find bug.
I will try your assume edi:ptr WINDOWCLASS idea, as long as the resulting call is 3 bytes(and it should be), I may use your method.
Thanks.
So?
F0_TABLE struct
pGetCommandLine DWORD ?
pGetLastError DWORD ?
pGetModuleHandle DWORD ?
F0_TABLE ends
.data?
FUNC0 F0_TABLE <>
.code
;;..FUNC0 needs filling in
mov ebp,OFFSET FUNC0
assume ebp:ptr F0_TABLE
call [ebp].pGetCommandLine
assume ebp:nothing
{syntax might need some tweaking, I haven't actually tested it.}
Looks like ASSUME wont work because you can ASSUME to the middle of a structure:
What I get:
00401006 8B 2D 04 40 40 00 mov ebp,dword ptr [api+4 (404004h)]
API STRUC
n4 dword ?
STRUC ZERO
zr dword ?
ENDS
p4 dword ?
API ENDS
assume ebp:ptr API
call [ebp].n4
0040100C FF 55 00 call dword ptr [ebp]
call [ebp].ZERO.zr
0040100F FF 55 04 call dword ptr [ebp+4]
call [ebp].p4
00401012 FF 55 08 call dword ptr [ebp+8]
What I want:
00401006 8B 2D 04 40 40 00 mov ebp,dword ptr [api+4 (404004h)]
assume ebp:ptr API
call [ebp].n4
0040100C FF 55 FC call dword ptr [ebp-4]
call [ebp].ZERO.zr
0040100F FF 55 00 call dword ptr [ebp]
call [ebp].p4
00401012 FF 55 04 call dword ptr [ebp+4]
The question is 0 to 255 the same as -7f t0 7f if its the same might as well use a 0 based approach.
Too tired to think about it now. Thanks.
Btw, you can make enumerations in MASM via a struct:
MyEnum struct
NONE db ? ; = 0
ONE db ? ; = 1
TWO db ? ; = 2
THREE db ? ; = 3
.... and so on
MyEnum ends
....
mov eax,MyEnum.TWO ; assembles into mov eax,2
RadASM supports intellisense for the above line
I usually name my enumerating-structs with a starting $, so the above enum would be $MyEnum, to make it clear to myself that this is an enumeration, and not a struct.
You're right!!! that what I was seeing when I was making my tests. It is still 0 based, but I could still get 63~64 3 byte calls per STRUCT
(256/ byte size of 32 bit ptr = 64)
Now I'll just have to expriment becuase I pretty sure if I use negative offsets I can extend that to 128 (well 127 or 126 depending on where the 0th element is).
Thanks.