1. ASM Help
- Posted by Matthew Lewis <matthewwalkerlewis at YAHOO.COM> Mar 21, 2001
- 468 views
I'm hoping someone here can help me out with some ASM. I'm trying to push some parameters on the stack, first of all, and then call a function to which I have a pointer. I've managed to move the params from memory to the stack, but I can't figure out how to call the other function. I've been using asm.e from Pete Eberlein, and he only has support for call near, which I don't think I can use here. So I've been poking around, and figured out how to put together opcodes for call far. Has anyone done anything like this? I've looked at a lot of stuff all over the web about ASM, and most of it really doesn't help, since it's usually geared toward MASM or the like, which is at a somewhat higher level than I'm working. Pete's docs doesn't seem to shed any light on this, either, although I found the encoding schemes for mnemonics at http://www.imada.ou.dk/~jews/PInfo/intel.html Here's my code (it's been modified somewhat at 1A from the original output). The function I want to call is located at comfunc (which I poke in after putting the routine into memory). I suspect part of my problem may be not pushing something (like the return address), but I've gotten the impression that call should do this automatically. com_asm = { #60, -- 0: pusha #BB,#00,#00,#00,#00, -- 1: mov ebx, paramcount (2) #8B,#0D,#00,#00,#00,#00,-- 6: mov ecx, [params] (8) #8B,#01, -- C: start: mov eax, [ecx] #50, -- E: push eax #83,#C1,#04, -- F: add ecx, 4 #4B, -- 12: dec ebx #75,#F7, -- 13: jnz start #B8,#00,#00,#00,#00, -- 15: mov edx, comfunc (22) #FF,#D8, -- 1A: call far eax #58, -- 1C: pop eax #A3,#00,#00,#00,#00, -- 1D: mov [retpointer], eax (30) #58, #58, #58, #61, -- 22: popa #C3}, -- 23: ret When I call the routine, I get a fault. Here's a dissasembly (the entry point is 00595610): ---------- Code Disassembly ---------- function: <nosymbols>+0000 0059560f 0060bb add [eax-0x45],ah ds:00f30b76=?? 00595612 0300 add eax,[eax] ds:00591f78=b7b85bc3 00595614 0000 add [eax],al ds:00591f78=c3 00595616 8b0d087e5900 mov ecx,[00597e08] ds:00597e08=00597df8 0059561c 8b01 mov eax,[ecx] ds:00597e04=00000011 0059561e 50 push eax 0059561f 83c104 add ecx,0x4 00595622 4b dec ebx 00595623 75f7 jnz 0059561c 00595625 b8781f5900 mov eax,0x591f78 FAULT ->0059562a ffd8 call eax 0059562c 58 pop eax 0059562d a300505659 mov [59565000],eax ds:59565000=???????? 00595632 005858 add [eax+0x58],bl ds:00f30b76=?? 00595635 61 popad 00595636 c3 ret 00595637 0920 or [eax],esp ds:00591f78=b7b85bc3 00595639 2020 and [eax],ah ds:00591f78=c3 0059563b 2011 and [ecx],dl ds:00597e04=11 0059563d 0000 add [eax],al ds:00591f78=c3 0059563f 0020 add [eax],ah ds:00591f78=c3 00595641 005900 add [ecx],bl ds:00f36a02=?? Registers: EAX: 00591F78 EBX: 00000000 ECX: 00597E04 EDX: 00000000 ESI: 00595610 EDI: 00000001 EIP: 0059562A ESP: 0056FC0C EBP: 0056FC46 IOPL: 0 nv up ei pl zr na po nc CS: 015F SS: 0167 DS: 0167 ES: 0167 FS: 59CF GS: 0000 EFL: 00010246 Stack: ---------- Top of the Stack ---------- 0056FC0C 00580030 00594E78 005F4250 00000001 |0.X.xNY.PB_.....| 0056FC1C 00595610 0056FC46 0056FC38 00000028 |.VY.F.V.8.V.(...| 0056FC2C 00000000 005A2644 005A2644 0041454C |....D&Z.D&Z.LEA.| 0056FC3C 005E0880 00000001 00423618 0056FC64 |..^......6B.d.V.| ---------- Stack Back Trace ---------- Stopped at 0059562A (0001:0059462A in (UNKNOWN)) Base=0x00000000 RVA=0x00001000 Matt Lewis
2. Re: ASM Help
- Posted by Mike The Spike <mtsreborn at yahoo.com> Mar 21, 2001
- 428 views
NP ma man... Here's how to fix this... Push the paremeters on the stack, and then do call(address_in_mem_of_function). Then pop the parameters. Easy huh? Just use Eu's call()... Mike The Spike --- Matthew Lewis <matthewwalkerlewis at YAHOO.COM> wrote: > > I'm hoping someone here can help me out with some > ASM. I'm trying to push > some parameters on the stack, first of all, and then > call a function to > which I have a pointer. I've managed to move the > params from memory to the > stack, but I can't figure out how to call the other > function. > > I've been using asm.e from Pete Eberlein, and he > only has support for call > near, which I don't think I can use here. So I've > been poking around, and > figured out how to put together opcodes for call > far. > > Has anyone done anything like this? I've looked at > a lot of stuff all over > the web about ASM, and most of it really doesn't > help, since it's usually > geared toward MASM or the like, which is at a > somewhat higher level than I'm > working. Pete's docs doesn't seem to shed any light > on this, either, > although I found the encoding schemes for mnemonics > at > http://www.imada.ou.dk/~jews/PInfo/intel.html > > > Here's my code (it's been modified somewhat at 1A > from the original output). > The function I want to call is located at comfunc > (which I poke in after > putting the routine into memory). I suspect part of > my problem may be not > pushing something (like the return address), but > I've gotten the impression > that call should do this automatically. > > com_asm = { > #60, -- 0: pusha > #BB,#00,#00,#00,#00, -- 1: mov ebx, > paramcount (2) > #8B,#0D,#00,#00,#00,#00,-- 6: mov ecx, > [params] (8) > #8B,#01, -- C: start: mov eax, > [ecx] > #50, -- E: push eax > #83,#C1,#04, -- F: add ecx, 4 > #4B, -- 12: dec ebx > #75,#F7, -- 13: jnz start > #B8,#00,#00,#00,#00, -- 15: mov edx, > comfunc (22) > #FF,#D8, -- 1A: call far eax > #58, -- 1C: pop eax > #A3,#00,#00,#00,#00, -- 1D: mov > [retpointer], eax (30) > #58, > #58, > #58, > #61, -- 22: popa > #C3}, -- 23: ret > > When I call the routine, I get a fault. Here's a > dissasembly (the entry > point is 00595610): > > ---------- Code Disassembly ---------- > function: <nosymbols>+0000 > 0059560f 0060bb add > [eax-0x45],ah > ds:00f30b76=?? > 00595612 0300 add eax,[eax] > ds:00591f78=b7b85bc3 > 00595614 0000 add [eax],al > ds:00591f78=c3 > 00595616 8b0d087e5900 mov > ecx,[00597e08] > ds:00597e08=00597df8 > 0059561c 8b01 mov eax,[ecx] > ds:00597e04=00000011 > 0059561e 50 push eax > 0059561f 83c104 add ecx,0x4 > 00595622 4b dec ebx > 00595623 75f7 jnz 0059561c > 00595625 b8781f5900 mov > eax,0x591f78 > FAULT ->0059562a ffd8 call eax > 0059562c 58 pop eax > 0059562d a300505659 mov > [59565000],eax > ds:59565000=???????? > 00595632 005858 add > [eax+0x58],bl > ds:00f30b76=?? > 00595635 61 popad > 00595636 c3 ret > 00595637 0920 or [eax],esp > ds:00591f78=b7b85bc3 > 00595639 2020 and [eax],ah > ds:00591f78=c3 > 0059563b 2011 and [ecx],dl > ds:00597e04=11 > 0059563d 0000 add [eax],al > ds:00591f78=c3 > 0059563f 0020 add [eax],ah > ds:00591f78=c3 > 00595641 005900 add [ecx],bl > ds:00f36a02=?? > > Registers: > EAX: 00591F78 EBX: 00000000 ECX: 00597E04 EDX: > 00000000 ESI: 00595610 EDI: > 00000001 > EIP: 0059562A ESP: 0056FC0C EBP: 0056FC46 IOPL: 0 > nv up ei pl zr na > po nc > CS: 015F SS: 0167 DS: 0167 ES: 0167 FS: 59CF > GS: 0000 EFL: > 00010246 > > Stack: > ---------- Top of the Stack ---------- > 0056FC0C 00580030 00594E78 005F4250 00000001 > |0.X.xNY.PB_.....| > 0056FC1C 00595610 0056FC46 0056FC38 00000028 > |.VY.F.V.8.V.(...| > 0056FC2C 00000000 005A2644 005A2644 0041454C > |....D&Z.D&Z.LEA.| > 0056FC3C 005E0880 00000001 00423618 0056FC64 > |..^......6B.d.V.| > > ---------- Stack Back Trace ---------- > Stopped at 0059562A (0001:0059462A in (UNKNOWN)) > Base=0x00000000 > RVA=0x00001000 > > Matt Lewis >
3. Re: ASM Help
- Posted by stabmaster_ at HOTMAIL.COM Mar 22, 2001
- 450 views
First of all, I see an evil typo in here. You're storing the adress to CALL in EDX, but you're CALLin EAX.. And you shouldn't use CALL FAR, but CALL NEAR. This is how to call a procedure (void) with one parameter: PUSH the_parameter MOV EAX, proc_address CALL NEAR EAX That's all there is to it, no need to pop anything. If you call a function (char, short, int), then the value of the function usually will be returned in EAX. E.g: ; pass the value of EBX to the function PUSH EBX MOV EAX, an_int_function CALL NEAR EAX ; did the function return 0 ? CMP EAX,0 ; do something.. >com_asm = { > #60, -- 0: pusha > #BB,#00,#00,#00,#00, -- 1: mov ebx, paramcount (2) > #8B,#0D,#00,#00,#00,#00,-- 6: mov ecx, [params] (8) > #8B,#01, -- C: start: mov eax, [ecx] > #50, -- E: push eax > #83,#C1,#04, -- F: add ecx, 4 > #4B, -- 12: dec ebx > #75,#F7, -- 13: jnz start > #B8,#00,#00,#00,#00, -- 15: mov edx, comfunc (22) > #FF,#D8, -- 1A: call far eax > #58, -- 1C: pop eax > #A3,#00,#00,#00,#00, -- 1D: mov [retpointer], eax (30) > #58, > #58, > #58, > #61, -- 22: popa > #C3}, -- 23: ret >
4. Re: ASM Help
- Posted by Robert Craig <rds at RapidEuphoria.com> Mar 22, 2001
- 445 views
Matt Lewis writes: > I wrote a little DLL (63K compressed) in VC that > will call the funcs by pointer, taking up to 10 arguments. > Rob, I'd like to add this to the wishlist: call > functions by pointer. Can't you use VC to disassemble, or generate an assembly listing of your .dll? Then you could poke the bytes of code into your Euphoria program, and eliminate the need for the .dll. Alternatively, you could get the address of the start of the dll routine, using '&' in C, and write the first 100 bytes or so to a file. I'm reluctant to add a feature that only one person has asked for, and even he doesn't really need it. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
5. Re: ASM Help
- Posted by Mike The Spike <mtsreborn at yahoo.com> Mar 22, 2001
- 462 views
Rob, to elaborate on my previous reply, I tested my point and he, I don't get a machine exception... hmm... Here's the source; include machine.e include get.e include file.e include dll.e integer FreeLibrary, GetProcAddress atom kernel32 kernel32 = open_dll("kernel32.dll") if kernel32 = 0 then puts(1,"Can't open kernel32.dll!!!\n") abort(1) end if FreeLibrary = define_c_func(kernel32, "FreeLibrary", {C_POINTER}, C_INT) if FreeLibrary = -1 then puts(1, "Can't find FreeLibrary!!!\n") abort(1) end if GetProcAddress = define_c_func(kernel32, "GetProcAddress", {C_POINTER, C_POINTER}, C_INT) if GetProcAddress = -1 then puts(1, "Can't find GetProcAddress!!!!!!\n") abort(1) end if -- Get address of a routine atom adress, str str = allocate_string("GetTickCount") adress = c_func(GetProcAddress,{kernel32,str}) -- Peek the routine from memory atom nloc,cnt,foo sequence code code = {} cnt = 0 while 1 do foo = peek(adress+cnt) if foo != #C3 then -- while not RET ... code = append(code,foo) cnt = cnt + 1 else code = append(code,foo) exit end if end while nloc = allocate(cnt) -- Now poke it all into memory again at a different location for i = 1 to length(code) do poke(nloc+i-1,code[i]) end for -- And finally call it: call(nloc) puts(1,"ALL DONE!") if wait_key() then end if --- Robert Craig <rds at RapidEuphoria.com> wrote: > > > Matt Lewis writes: > > I wrote a little DLL (63K compressed) in VC that > > will call the funcs by pointer, taking up to 10 > arguments. > > Rob, I'd like to add this to the wishlist: call > > functions by pointer. > > Can't you use VC to disassemble, or generate an > assembly listing of your .dll? Then you could > poke the bytes of code into your Euphoria program, > and eliminate the need for the .dll. Alternatively, > you could get the address of the start of the dll > routine, > using '&' in C, and write the first 100 bytes or so > to a file. > > I'm reluctant to add a feature > that only one person has asked for, > and even he doesn't really need it. > > Regards, > Rob Craig > Rapid Deployment Software > http://www.RapidEuphoria.com > > > >
6. Re: ASM Help
- Posted by Mike The Spike <mtsreborn at yahoo.com> Mar 22, 2001
- 465 views
> Matt Lewis writes: > > I wrote a little DLL (63K compressed) in VC that > > will call the funcs by pointer, taking up to 10 > arguments. > > Rob, I'd like to add this to the wishlist: call > > functions by pointer. > > Can't you use VC to disassemble, or generate an > assembly listing of your .dll? Then you could > poke the bytes of code into your Euphoria program, > and eliminate the need for the .dll. Alternatively, > you could get the address of the start of the dll > routine, > using '&' in C, and write the first 100 bytes or so > to a file. *ahem* Err... Rob? That's like, impossible ya know? It seems as if this is possible at first, but you're only making a fool out of yourself keeping those instructions in Eu's docs... Why? Because if I have a routine that does this; int crap; void doit() { crap = 1; } void showit() { printf("%d",crap); } main() { doit(); showit(); } Then if you're going to 'download' routine 'showit' from memory, and poke it somewhere else, and then call it, it's gonna cause an error because 'crap' hasn't being initialised yet. This is a simple example, but in reality it's all more complex than this, and doing what your propose, is going to leave you with a bunch of machine codes, acting upon data that just isn't there! Mike The Spike > I'm reluctant to add a feature > that only one person has asked for, > and even he doesn't really need it. > > Regards, > Rob Craig > Rapid Deployment Software > http://www.RapidEuphoria.com > >