Jump to content
Tuts 4 You

How to assemble text to binary code for MASM?


LCF-AT

Recommended Posts

Posted

Hi guys,

I am looking for a lib which can assemble text commands to binary code.Something like the Multiline Ultimate Assembler plugin by RaMMicHaeL.I do enter my code as text and wanna assemble it.

Ok,normaly I can use Disam lib from OllyDBG site using function Assemble to assemble text commands one by one.Problem is I wanna work also with labels and API names etc alomst same as the MUA plugin can do.Has anyone some ideas what I could use for that?

Thank you

Posted

You could rip out Cheat Engines assembler to do this if you are familiar with Delphi.

  • Like 1
Posted

There is fasm.dll which contains core of Flat Assembler. It has some limitations but should be able to handle simple things like assembling a code snippet.

Starting point: https://board.flatassembler.net/topic.php?t=6239 , after that-Google is your friend..

  • Like 2
Posted

Hi guys,

thanks for your answers so far.No plan about Delphi stuff,just coding with MASM etc.

About Flat Assembler.I have test the dll with that fasm_Assemble function a little.I am not sure whether this could be a solution for me but I am still testing so far.Problem is that I wanna read the entered text code by user and build it temporary in a memory section with a desired other memory location address.With disam lib / assemble function its doable but there I have the problem that I cant use labels as I told before.

Does anyone know how the MUA plugin does it?Does it use any engine or is it selfmade?

Simple example:

xor eax,eax
call 401000h
jmp @F
nop
ret
@@:
nop
ret

With disam lib / assemble function I can set a desired mem location where to assemble the command to so that I get the right opcodes for dynamic constanzes.All fine but for labels its not working etc.

greetz

null_endian
Posted (edited)

@LCF-AT have you tried Binary Ninja's API? Visit that link, look around and see if it could be useful to you...

Edited by null_endian
  • Like 1
Posted

honestly, restricting yourself with MASM will maximize the difficulty of your job.

  • Like 3
Posted (edited)
19 hours ago, LCF-AT said:

Hi guys,

thanks for your answers so far.No plan about Delphi stuff,just coding with MASM etc.

About Flat Assembler.I have test the dll with that fasm_Assemble function a little.I am not sure whether this could be a solution for me but I am still testing so far.Problem is that I wanna read the entered text code by user and build it temporary in a memory section with a desired other memory location address.With disam lib / assemble function its doable but there I have the problem that I cant use labels as I told before.

Does anyone know how the MUA plugin does it?Does it use any engine or is it selfmade?

Simple example:


xor eax,eax
call 401000h
jmp @F
nop
ret
@@:
nop
ret

With disam lib / assemble function I can set a desired mem location where to assemble the command to so that I get the right opcodes for dynamic constanzes.All fine but for labels its not working etc.

greetz

Hi there,

I believe you might have figured it out already. Anyway here is a C# code if that helps. You might have to install both FASM & MemorySharp NuGets to pull this off.

Here is a sample code.

// Get the .Net Process
Process NetProcess = Process.GetProcessById(PIDe); 

// Create the assembler to assemble the jmp commands.
MemorySharp TargetMemShrpObj = new MemorySharp(NetProcess.Id); // or just put Process.GetCurrentProcess()

// Convert data bytes to 32-bit Address.
Jmpaddr = BitConverter.ToInt32(buffer, 0);

// Assemble the Jmp instructions. startaddr: Addr. where the jump is assembled, its a relative jump you see.
var XOpCod = TargetMemShrpObj.Assembly.Assembler.Assemble("jmp 0x" + (Jmpaddr - startaddr).ToString("X"));

// Replace Far-Jumps with jumps to Destination Address.
WStatStr = WriteProcessMemory(processHandle, startaddr, XOpCod, XOpCod.Length, ref bytesWritten) ?
"\t-> Success!" : "\t-> Error!";

NuGet Package Manager:

P8gbqQi.png

Hope this was useful.

Respects & Regards,

Ben

Edited by Benten
  • Like 2
Posted

Hi again,

I am still testing the FASM dll and get some trouble to build simple text to code.

jmp @A1
nop
@A1:
mov eax, 401000h
ret

API returns 0 = success but the code is this...

02300100   /EB 01                   JMP SHORT 02300103
02300102   |90                      NOP
02300103   \66:B8 0010              MOV AX,0x1000
02300107    40                      INC EAX
02300108    00C3                    ADD BL,AL

The label jumps wrong.Why?Or the 66 byte is wrong = not needed.Has or can anyone write a small example code using some labels + basic stuff I can use with the fasm_Assemble function what also works?Just for testing so I just wanna build temporary codes at the moment no full files etc.Would be nice. :)

greetz

Posted (edited)

you sure you told it to compile in 32 bit ? cos the 66 is definitely wrong

 

00000000`00000400: EB01                        jmps         000000403
00000000`00000402: 90                             nop
00000000`00000403: B800104000           mov          eax,000401000
00000000`00000408: C3                             retn

Edited by evlncrn8
  • Like 1
Posted

Hi,

00241000 >PUSH 0x0
00241002  PUSH 0x100
00241007  PUSH 0x1000                  ; mem size
0024100C  PUSH 0x2300000               ; mem
00241011  PUSH 0x12B0000               ; ASM TEXT
00241016  CALL 73CD3023                ; FASM.fasm_Assemble

Where to tell?Just using my small example code above in memory and called it as above with that function.Did I forget something?

greetz

CodeExplorer
Posted
On 4/16/2018 at 8:25 PM, Kurapica said:

honestly, restricting yourself with MASM will maximize the difficulty of your job.

MASM is good, but a program written in any assembler language is hard to maintain.
 

  • Like 2
Posted

have to agree there, esp now with 64 bit too, theres a lot of maintainance to do, use asm for stuff that can benefit you, like a nice speedy algo or something, but for most of the stuff i switched to c/c++, mostly from work requirements, for example pid 7, im doing mostly in c/c++, some of the scanning algos in asm, but the core in c cos its so much easier to maintain and also do 32 and 64 bit with ease

  • Like 1
Posted (edited)
1 hour ago, LCF-AT said:

Hi again,

I am still testing the FASM dll and get some trouble to build simple text to code.


jmp @A1
nop
@A1:
mov eax, 401000h
ret

API returns 0 = success but the code is this...


02300100   /EB 01                   JMP SHORT 02300103
02300102   |90                      NOP
02300103   \66:B8 0010              MOV AX,0x1000
02300107    40                      INC EAX
02300108    00C3                    ADD BL,AL

The label jumps wrong.Why?Or the 66 byte is wrong = not needed.Has or can anyone write a small example code using some labels + basic stuff I can use with the fasm_Assemble function what also works?Just for testing so I just wanna build temporary codes at the moment no full files etc.Would be nice. :)

greetz

Dear LCF-AT,

I believe, Flat Assembler's default Output is 16-bit so all you need to do is switch it to 32-bit with the use32 directive

Please refer

Quote

Also to see it in action visit (whats happening to your code)

Quote

What you actually need

Quote

Highest Regards,

Ben

Edited by Benten
  • Like 1
  • Thanks 1
Posted

Add "use32" to the beginning of your code to specify 32bit mode, there is also "org 0xaddress" to specify base of the code

 

  • Like 1
Posted

Hi again,

thanks for new infos so far guys.Ok I have test to set use32 at the top and this works now. :) One success so far.So do you have more examples what to use etc?

use32
jmp @f
nop
@@:
mov eax, 401000h
push eax
pop @free
push @source
call eax
ret


@source db 'hallo',00h
@free   dd ?

greetz
 

Posted (edited)

The easy way to check your code and see syntax errors is using FASMW.exe (found at https://flatassembler.net/fasmw172.zip) , using it with your code it' gave me  an "invalid operand" error in "pop @free", you fix it with "pop dword[@free]"

By disassembling back the generated file (using ollyDbg > view > file > left click > disassemble) I found that the "@free dd ?" has generated only one byte, use "@free dd 0" instead to generate 4  bytes

 

See the following example for more info (it's a code of a function that gets the handle of a module from it's name's hash)

Spoiler

use32
GMH:
push ebp
mov ebp, esp
sub esp, 8
mov eax, dword [fs:0x30]
mov eax, dword [eax+0xC]
mov eax, dword [eax+0xC]
mov dword [ebp-0x8], eax
push dword [eax+0x4]
pop dword [ebp-0x4]
Jmp @L66BD

@L669D:
mov eax, dword [eax+0x30]
push eax
Call @HashW
cmp eax, dword [ebp+0x8]
Jne @L66B5
mov eax, dword [ebp-0x8]
mov eax, dword [eax+0x18]
leave
retn 0x4

@L66B5:
mov eax, dword [ebp-0x8]
mov eax, dword [eax]
mov dword [ebp-0x8], eax

@L66BD:
cmp eax, dword [ebp-0x4]
Jne @L669D
mov eax, 0xFFFFFFFF
leave
retn 0x4

@HashW:
push ebp
mov ebp, esp
mov edx, dword [ebp+0x8]
xor eax, eax
Jmp @L66F2

@L66D5:
mov cl, byte [edx]
cmp cl, 0x61
Jl @L66EC
cmp cl, 0x7A
Jg @L66EC
sub cl, 0x20

@L66EC:
xor al, cl
rol eax, cl
inc edx
inc edx

@L66F2:
cmp word [edx], 0x0
Jne @L66D5
leave
retn 0x4

 

Edited by cob_258
  • Like 1
Posted

Hi again and thanks,

ok I try the main FASM file to assemble some test cdoes till success / or no invalid message.Now I load file in Olly (load mem) to see assembled code.

use32
jmp @f
nop
@@:
mov eax, 401000h
push eax
pop [@free]
push @source
call eax
ret


@source db 'hallo',00h
@free   dd 0   

in Olly =

$ ==>    01CA0000    /EB 01                   JMP SHORT 01CA0003
$+2      01CA0002    |90                      NOP
$+3      01CA0003    \B8 20104020             MOV EAX,0x20401020
$+8      01CA0008     50                      PUSH EAX
$+9      01CA0009     8F05 1A202020           POP DWORD PTR DS:[0x2020201A]
$+F      01CA000F     6A 14                   PUSH 0x14
$+11     01CA0011     FFD0                    CALL EAX
$+13     01CA0013     C3                      RETN
$+14     01CA0014     68 616C6C6F             PUSH 0x6F6C6C61
$+19     01CA0019     2020                    AND BYTE PTR DS:[EAX],AH
$+1B     01CA001B     2020                    AND BYTE PTR DS:[EAX],AH
$+1D     01CA001D     2000                    AND BYTE PTR DS:[EAX],AL

$+14     01CA0014   68 61 6C 6C 6F 20 20 20 20 20 00 00 00 00 00 00  hallo     ......

Question: Can I set also a memory location address same as the function where to assemble that code?Why are some values wrong like mov eax, 401000h etc?Why are using space bytes after the string?

PS: Quick other question about Olly.Is there a way to load my text file into ASCII dump?Just need it to use it with the function and can just copy / paste manually some text lenght into dump.I dont wanna use Olly script now to load my text and thought it would be also possible anyhow else quickly.

greetz

Posted

I assembled exactly the same code above and obtained the correct dump and no extra spaces after the string, maybe you're using a different version 

image.png.8ced5f6573d9a7f39addb6bca44c6dbb.png

To load the code in ASCCI dump copy it (the code) to clipboard, select the memory where you wan't to paste it, ctrl+E and paste it in ASCII's textbox then ok

image.png.d66ef7998a5b7475e551a69c7866416b.png

  • Like 1
Posted

Hi,

ok I see I did something wrong and just did copy / paste the bin file.Now I load it and I see same as you got.

About text copy / paste.Problem is that it only does paste 100 bytes and thats to less if I have more text.

Ok I will test go on with that now.Also just need to find out how to handle API text like call GetProcAddress etc.

Thanks again so far and till later.If you got some more example codes what does include some more (all possible things I can do to see how to declare it without making a standalone PE file) then just post it. :)

greetz

Posted

Hi again,

so I have another add on question.I wanna create a edit control or RichEdit where the user can enter the ASM commands and this I wanna let highlight in diffrent colors (Syntax Highlight).Is there a way to make this simple without to check the entire text in realtime?In the MUA plugin I can see its using SendDlgItemMessageA for diffrent words on loading...

0012D268   714D18B0  /CALL to SendDlgItemMessageA from multiasm.714D18AE
0012D26C   0005038C  |hWnd = 0005038C ('Multiline Ultimate Assembler',class='#32770',parent=00080222)
0012D270   000003EA  |ControlID = 3EA (1002.)
0012D274   000007E8  |Message = MSG(0x7E8)  ;WM_CPL_LAUNCH
0012D278   00FF0000  |wParam = 0xFF0000
0012D27C   714DB5D0  \lParam = 0x714DB5D0

714DB5D0  61 61 61 20 61 61 64 20 61 61 6D 20 61 61 73 20  aaa aad aam aas
714DB5E0  61 64 63 20 61 64 64 20 61 6E 64 20 63 61 6C 6C  adc add and call
714DB5F0  20 63 62 77 20 63 6C 63 20 63 6C 64 20 63 6C 69   cbw clc cld cli
714DB600  20 63 6D 63 20 63 6D 70                           cmc cmp

....just wanna know whether I can do it on any similar way too?Maybe anyone has some clue how to do it etc.

Thanks you

Posted

Hi,

I tested the tuts already but I have  problem with that subclass of NewRichEditProc and it crashes.I am using not the GetMessage loop in my codes etc just using DLGProc / DialogBoxParam for my main proc.

Can I use this anyhow RAEdit stuff in masm?I dont think so.

greetz

Posted

Hi,

if I load the files of tut35 into WinASM then the created file crashs too.Why this?Also same reason of subclassing.

		invoke SetWindowLong,hwndRichEdit,GWL_WNDPROC, addr NewRichEditProc
		mov OldWndProc,eax

If I not use it then it starts or else it crashs in the NewRichEditProc routine (stack empty).Strange.

greetz

Posted

 

is hwndRichEdit correct ?

does SetWindowLong return successfully ?

is the subclassed function calling the original function correctly and returning correctly ?

 

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...