flat assembler
Message board for the users of flat assembler.

Index > Main > Code translates into wrong target

Author
Thread Post new topic Reply to topic
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
Hi,

i am pretty new to the fasm assembler and i must confess, i do have "ZERO" assembly language knowledge compared to others here. Before i posted this question, i had a look in the faq, did a search in the board, also try to find any information in the documentation, but unfortunately i couldnt find a answer to my question. I try to load machine code "dynamically" from a binary file into my C program and execute it by allocating memory, mark it executable and get a pointer to it by using a function pointer cast to the memory filled with the binary code. Finally i call the function and get the result. In general i am doing this not that way, instead i use a library with exported functions or a static library to incorporate code into my application. Here comes the problem:

I try to assemble e.g. these simple instructions into a "flat" file (i am using fasmw 1.70.03 and i simply enter these instructions (without any prolouge/epilouge) in the IDE:


mov eax,[esp+8]
mov ecx,[esp+4]
add eax,ecx
ret 8


where flat stands for the raw assembling into machine code, without any sections/headers etc. But the result i get seems to be using only the 16 it parts of the registers (which for sure isnt the problem at all) and the rest is "padded" somehow. But trying to load and execute this (i am on nt based windows 32 bit) fails with an access violation. The translation into binary code ends up in this:

Dump of File Image
0x00000000 67 66 8B 44 24 08 67 66 8B 4C 24 04 66 01 C8 C2 gf.D$.gf.L$.f... +00
0x00000010 08 00 .. +10

and decompiles into this:

MOV AX,WORD PTR [ESP+0x8]
MOV CX,WORD PTR [ESP+0x4]
ADD AX,CX
RET 0x8

but i need this which i get by doing hex editing the final result:

Dump of File Image
0x00000000 8B 44 24 08 8B 4C 24 04 01 C8 C2 08 00 .D$..L$...... +00

which correctly decompiles into the original instructions:

MOV EAX,DWORD PTR [ESP+0x8]
MOV ECX,DWORD PTR [ESP+0x4]
ADD EAX,ECX
RET 0x8

and this can be executed without any problems.

What can i do, to get the the result i want? I guess its some meta instruction in the source files header, but i couldnt find anything than could help me.

thanks in advance

TRP
Post 28 Jan 2013, 03:24
View user's profile Send private message Reply with quote
Spool



Joined: 08 Jan 2013
Posts: 154
Spool
[ Post removed by author. ]


Last edited by Spool on 17 Mar 2013, 04:43; edited 1 time in total
Post 28 Jan 2013, 03:41
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
Spool wrote:
You should load the compiled code in VirtualAlloc(...) and VirtualProtect(...) with PAGE_EXECUTE in case in if your using Windows. The executable code must be aligned by 16bytes padded with nops.


VirtualAlloc, VirtualProtect, VirtualFree is clear so far and the way i am doing it already, but what do you mean with 16bytes padded with no operation instructions?
Post 28 Jan 2013, 04:09
View user's profile Send private message Reply with quote
Spool



Joined: 08 Jan 2013
Posts: 154
Spool
[ Post removed by author. ]


Last edited by Spool on 17 Mar 2013, 04:43; edited 1 time in total
Post 28 Jan 2013, 04:17
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
Spool wrote:
Quote:

do you mean with 16bytes padded with no operation instructions?



if you have 15 bytes of compiled code then add 1 byte NOP
if you have 40 bytes of compiled code then add 8 bytes filled with NOP

like:
mov eax,[esp+8]
mov ecx,[esp+4]
add eax,ecx
ret 8
nop
...


AFAIU this is the multiple of 16 and if yes, why the multiple of 16? I had 18 bytes on the original output and i nop'ed it to 32 bit, but it still looks like this:

0x00000000 67668B442408 MOV AX,WORD PTR [ESP+0x8]
0x00000006 67668B4C2404 MOV CX,WORD PTR [ESP+0x4]
0x0000000C 6601C8 ADD AX,CX
0x0000000F C20800 RET 0x8
0x00000012 90 NOP
0x00000013 90 NOP
0x00000014 90 NOP
0x00000015 90 NOP
0x00000016 90 NOP
0x00000017 90 NOP
0x00000018 90 NOP
0x00000019 90 NOP
0x0000001A 90 NOP
0x0000001B 90 NOP
0x0000001C 90 NOP
0x0000001D 90 NOP
0x0000001E 90 NOP
0x0000001F 90 NOP
Post 28 Jan 2013, 04:31
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
use32
Post 28 Jan 2013, 04:35
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
I found it, its the use32 directive that must be placed in thea sources header section.
Post 28 Jan 2013, 04:44
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
sinsi wrote:
use32


Yes, i found it, its documented here:

http://flatassembler.net/docs.php?article=manual#2.4

Thanky you anyway. Smile
Post 28 Jan 2013, 04:46
View user's profile Send private message Reply with quote
Spool



Joined: 08 Jan 2013
Posts: 154
Spool
[ Post removed by author. ]


Last edited by Spool on 17 Mar 2013, 04:44; edited 2 times in total
Post 28 Jan 2013, 04:50
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
Spool wrote:
here its workable:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
unsigned char *buf = malloc(32);

buf[0] = 0x8b;
buf[1] = 0x44;
buf[2] = 0x24;
...
result is 3


Thank you for the example, but this could "possibly" not work in Windows and could possibly also not work in *nix systems and its also not eaxctly the answer to my OP. The OP question was how i could make the input assembly instructions go output into 32 bit assembly and not the 16 bit variant. Your example uses correct bytes to run, but you are using the wrong methods. As you pointed out by yourself, one should use the Virtual* functions, but malloc() uses internall malloc->HeapAlloc->RtlAllocateHeap accross three dynamic link libraries and the heap allocated memory could, must not be executable due to memory protection mechanisms. This could lead to a segmentation fault. In *nix you use mmap() and mprotect() for this. Even though the memory will be freed by the OS kernel on app termination, one should always use free() on *nix or VirtualFree() on Windows systems to release the memory previously allocated.
Post 28 Jan 2013, 05:22
View user's profile Send private message Reply with quote
Spool



Joined: 08 Jan 2013
Posts: 154
Spool
[ Post removed by author. ]


Last edited by Spool on 17 Mar 2013, 04:44; edited 1 time in total
Post 28 Jan 2013, 05:29
View user's profile Send private message Reply with quote
TheRedPill



Joined: 28 Jan 2013
Posts: 18
TheRedPill
Spool wrote:
The code above can be 16-bit or 32-bit but Windows application running without compatibility is 32-bit.
I'm not sure if it is working on *nix sys. I have tried running this code.


I guess it "can" work on *nix systems, but if memory protection comes in, it will fail in some way.
Post 28 Jan 2013, 05:34
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.