1. ASM Help

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

new topic     » topic index » view message » categorize

2. Re: ASM Help

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
>

new topic     » goto parent     » topic index » view message » categorize

3. Re: ASM Help

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
>

new topic     » goto parent     » topic index » view message » categorize

4. Re: ASM Help

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: ASM Help

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
> 
> 
>
>

new topic     » goto parent     » topic index » view message » categorize

6. Re: ASM Help

> 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
>
>

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu