Jump to content
Tuts 4 You

How to assemble text to binary code for MASM?


LCF-AT

Recommended Posts

16 hours ago, LCF-AT said:

if I load the files of tut35 into WinASM .. it crashs in the NewRichEditProc routine (stack empty).

It's not an empty stack, it's a stack overflow. :)

 

If you look at original iczedit.exe (available in https://tuts4you.com/e107_plugins/download/request.php?id=1200 , CHM->Tutorial 35->Download the example), you'll see that it has stack reserve & commit = 2000000 bytes. By default, Microsoft link.exe uses values 1048576 and 4096. Change those and it will work just fine.

Command line should look something like this (not using WinASM, so I don't know the exact steps you need to take):

c:\masm32\bin\Link /SUBSYSTEM:WINDOWS /OPT:NOREF /STACK:2000000,2000000 %1.obj rsrc.obj

 

  • Like 2
Link to comment

Hi guys,

thanks again.Ok now I see it.The NewRichEditProc in this example did use a local buffer of 1024*10. :) Pretty much.My compiler settings = this...

/SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0

...does it mean that I only should add /STACK:2000000,2000000.....ok I have test it with adding stack and it works without crashing anymore. :) Thanks for this new info about it kao.

Now I have one more small question about that tut35 example.So I would like to use a specific font for the RichEdit and have some problems with that.First I dont see what it used as default font for this RichEdit control (I dont use resource file of tut 35) but it look like in the original 35 file.Now I tried to change the font using CreateFont & WM_SETFONT to set my new font and this is also shown but if it gets colored (if I enter mov for example) then it does change and gets smudged anyhow like this...

Font.png.4e1647bedc2dba8ed348bfa342816197.png

...so how can I make it match without to get that overlapping issues?

greetz

Link to comment

Hi,

I tried to change the font here....

SetColor proc
	LOCAL cfm:CHARFORMAT
	invoke SendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,rgb(255,255,225);BackgroundColor
	invoke RtlZeroMemory,addr cfm,sizeof cfm
	mov cfm.cbSize,sizeof cfm
	mov cfm.dwMask, CFM_FACE	
	invoke lstrcpy,addr cfm.szFaceName,chr$("Comic Sans MS")
	mov cfm.yHeight,220
	invoke SendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addr cfm
	ret
SetColor endp

....just for testing.Now I get to see comic sans font with 220 hight.First problem its some kind of bold no idea why so I didnt set bold.Now if it gets colored by matching words then its also getting overlapped again what I dont check yet.In the NewRichEditProc its reading the char rect and does draw the color over it but it dosent match...

Font2.png.a73b7fdae3e1e82c050114a5a80d162e.png

and with using CFM_SIZE in dwMask and yHeight,400 = this...

Font3.png.9c870eedf604b217eea0177d0cc48fa4.png

...so how do I get this matching to the font / size I did set in CHARFORMAT / EM_SETCHARFORMAT?Also this BOLD thing is bad.

greetz

Link to comment

I studied a little bit (not deeply) the code of SimEd.exe (at https://sourceforge.net/p/fbedit/code/HEAD/tree/SimEd/) and found that it loads RAEdit.dll, the control that show highlighted code have the class of "RAEdit" (which is registered by RAEdit.dll using RegisterClassExA)

image.png.a304ce13e0e645bf2cb46da829e99755.png

 

To set syntax highlight read the "SetKeyWords proc hWin:HWND" in  simed\simed\misc.asm (or at 0x4014BC in SimEd.exe)


image.png.f656423dc8f01a8015a8f533c988446f.png

 

TL;DR  : 

  • set HiLiteControl's class = "RAEdit"
  • at WM_INITDIALOG use "invoke SendMessage,hHiLiteControl, REM_SETHILITEWORDS, dwColor,lpstrGroup"
Edited by cob_258
  • Like 1
Link to comment

Hi,

not sure what to use now so its again something else.Do you have some more detailed example for this etc?What is dwColor,lpstrGroup?I dont see it in the RAEdit.inc.

Still fighting with that font trash problem I dont get fixed yet. :(

greetz

Link to comment

by setting a BP on 40155A (I'm debugging SimEd.exe) we notice that the last parameter (lpstrGroup) is a pointer to string that contains the words that has should be colored by dwColor which is the 0x00BBGGRR (B = blue, G = green, R = red) encoded color 

see the stack below, these are the parameters of SendMessageA at 40155A :

image.png.5694ea3f8be5c13bb5b2c5072106992b.png

 

we also have this from Raedit.inc

REM_SETHILITEWORDS        equ REM_BASE+0        ;wParam=Color, lParam=lpszWords

-----------------------------------------------------------------

this is a quickly written example in masm (I use WinAsm IDE) 

RaeTest.rar

 

the examples set's colors only for registers (I'm lazy xD)

image.png.9eef5d5f880d01cdcc798b985a7a2d38.png

 

BTW thanks to @fearless for the link to the library

 

Edited by cob_258
  • Like 1
Link to comment
13 hours ago, LCF-AT said:

.Now I get to see comic sans font with 220 hight.First problem its some kind of bold no idea why so I didnt set bold  ... its reading the char rect and does draw the color over it but it dosent match...

1) Start with basics and read Tutorial 33. :) You did not set dwMask field correctly, that's why font keeps previous setting (bold).
2) Read the actual text of Tutorial 35 - it explains how syntax highlighting is implemented. In short - you should not change font *inside* the SetColor method. If you set it when creating RichEdit, it should work fine.

 

  • Like 1
Link to comment

Hi guys,

thanks again for your answers.Ok,slowly I do understand the RAEdit control. :) Playing around a little to set some diffrent paramters etc and it works so far also setting cusom fonts / colors.I have a question about it so I cant find all infos in the inc file like...GetCharTabPtr so whats this?Something with the tabs.

Ok kao,so I tried to set the font only after creating the RichEdit control and its working same bad what means I get to see my set font but if it gets colored then it also dosent match = double as you can see on my pics I made.Also get same bad results if I change font in SetColor proc. :( Thats also the reason why I did start to change that SetColor proc CHARFORMAT struct because WM_SETFONT wasnt enough to get both matched (normal & colored text) you know.

greetz

 

Link to comment

The definition of GetCharTabPtr is in RAEdit.asm

Spoiler

GetCharTabPtr proc public

    mov        eax,offset CharTab
    ret

GetCharTabPtr endp

 

CharTab in Data.inc

Spoiler

CharTab                    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;00
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;10
                        ;    ! " # $ % & ' ( ) * + , - . /
                        db 0,2,5,3,2,2,2,5,2,2,2,2,2,2,3,2        ;20
                        ;  0 1 2 3 4 5 6 7 8 9 : ; < = > ?
                        db 1,1,1,1,1,1,1,1,1,1,2,4,2,2,2,3        ;30
                        ;  @ A B C D E F G H I J K L M N O
                        db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1        ;40
                        ;  P Q R S T U V W X Y Z [ \ ] ^ _
                        db 1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1        ;50
                        ;  ` a b c d e f g h i j k l m n o
                        db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1        ;60
                        ;  p q r s t u v w x y z { | } ~
                        db 1,1,1,1,1,1,1,1,1,1,1,2,2,2,0,0        ;70

                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;80
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;90
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;A0
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;B0
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;C0
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;D0
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;E0
                        db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0        ;F0

 

and this is the meaning of these values (in RAEdit.inc)

Spoiler

;Character table types
CT_NONE                    equ 0
CT_CHAR                    equ 1
CT_OPER                    equ 2
CT_HICHAR                equ 3
CT_CMNTCHAR                equ 4
CT_STRING                equ 5
CT_CMNTDBLCHAR            equ 6
CT_CMNTINITCHAR            equ 7

 

I guess it's a table to redefine the meaning/type of every character and it has nothing to do with tabs 

  • Like 1
Link to comment

Hi guys,

thanks again so far for the help.I think I will use the RAEdit control which I got working now so far with my settings I wanna use to have a user interface to enter ASM commands.For reading the entred commands I will use FASM to get the binary code temporary but also here I need to add some extra stuff for using specific APIs for example what FASM cant handle.I think about something like that..

call (GetProcAddress|kernel32.dll)

...using some brackets (|) syntax for API | dll which I do check before and change then to direct address before using it with FASM.Still thinking about it.If I got this working then I use DIASM lib to adjust binary code to new desired temporary location which I then inject into any process or new process I want or to build a loader file with hook engine together.Main goal is just to build something whats pretty easy to use later for the user (also on fly for testing) without to care about hooking & special code and adjustments.No idea whether there is already any tool like that or not but I dont think so.

greetz

Link to comment

Hi guys,

short question.I did subclass my RAEdit control to my proc and wanna catch WM_KEYDOWN / UP etc but I dont get it there.How can I get these messages too now?Was it any style or ExStyle I need to set etc?

greetz

Link to comment
call [kernel32.GetProcAddress]

would be a better way, nt internal style, where for ordinals its module.#1234 for example, makes things a lot easier to parse

  • Like 1
Link to comment
14 hours ago, LCF-AT said:

Hi guys,

short question.I did subclass my RAEdit control to my proc and wanna catch WM_KEYDOWN / UP etc but I dont get it there.How can I get these messages too now?Was it any style or ExStyle I need to set etc?

greetz

Have to use a proper windows message loop with IsDialogMessage function in that loop as well. No styles or exstyles will help fix this. Gonna have to learn to use that at some time, might as well be now.

  • Like 2
Link to comment

Hi,

ah ok seems I need to use this loop in some cases. :(

So I have a other problem now.If I destory my RAEDIT handle then the whole app does close.Before it was not so and everything was working well without that problem.Now I cant find out why it does exit.I just use DestroyWindow API and then its over.So how to prevent that?If I not use DestroyWindow function then all keeps running but I need to destroy them.Has anyone some hints how to handle that without to change the source so long till the problem was found etc?

Thanks

Link to comment

Hi again,

ok I found out.

      .elseif uMsg==WM_DESTROY
		    invoke PostQuitMessage,NULL 

I am using that code in my subclass of RAEDIT and it does close whole app if I destory a RAEDIT handle.Not sure why so in my other contol suclasses I use it too like tabs etc.In some I get no problems in some yes!=?

greetz

Link to comment

Hi again,

I have a question about FASM struct FASM_STATE.

FASM_STATE struct 
  condition dd ?
  union
    output_length dd ?
    error_code dd ?
  ends
  union
    output_data dd ?
    error_line dd ?
  ends
FASM_STATE ends

So there are 3 dword locations to get datas back after calling fasm_Assemble function.If the function returns FASM_OK then all 3 struct locations was filled fine but if the function returns FASM_ERROR

FASM_OK 			 = 0	; FASM_STATE points to output
FASM_ERROR			 = 2	; FASM_STATE contains error code


; Error codes for FASM_ERROR condition

FASMERR_FILE_NOT_FOUND			    = -101
FASMERR_ERROR_READING_FILE		    = -102
FASMERR_INVALID_FILE_FORMAT		    = -103
FASMERR_INVALID_MACRO_ARGUMENTS 	    = -104
FASMERR_INCOMPLETE_MACRO		    = -105
FASMERR_UNEXPECTED_CHARACTERS		    = -106
FASMERR_INVALID_ARGUMENT		    = -107
FASMERR_ILLEGAL_INSTRUCTION		    = -108
FASMERR_INVALID_OPERAND 		    = -109
FASMERR_INVALID_OPERAND_SIZE		    = -110
FASMERR_OPERAND_SIZE_NOT_SPECIFIED	    = -111
FASMERR_OPERAND_SIZES_DO_NOT_MATCH	    = -112
FASMERR_INVALID_ADDRESS_SIZE		    = -113
FASMERR_ADDRESS_SIZES_DO_NOT_AGREE	    = -114
FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS = -115
FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE	    = -116
FASMERR_RELATIVE_JUMP_OUT_OF_RANGE	    = -117
FASMERR_INVALID_EXPRESSION		    = -118
FASMERR_INVALID_ADDRESS 		    = -119
FASMERR_INVALID_VALUE			    = -120
FASMERR_VALUE_OUT_OF_RANGE		    = -121
FASMERR_UNDEFINED_SYMBOL		    = -122
FASMERR_INVALID_USE_OF_SYMBOL		    = -123
FASMERR_NAME_TOO_LONG			    = -124
FASMERR_INVALID_NAME			    = -125
FASMERR_RESERVED_WORD_USED_AS_SYMBOL	    = -126
FASMERR_SYMBOL_ALREADY_DEFINED		    = -127
FASMERR_MISSING_END_QUOTE		    = -128
FASMERR_MISSING_END_DIRECTIVE		    = -129
FASMERR_UNEXPECTED_INSTRUCTION		    = -130
FASMERR_EXTRA_CHARACTERS_ON_LINE	    = -131
FASMERR_SECTION_NOT_ALIGNED_ENOUGH	    = -132
FASMERR_SETTING_ALREADY_SPECIFIED	    = -133
FASMERR_DATA_ALREADY_DEFINED		    = -134
FASMERR_TOO_MANY_REPEATS		    = -135
FASMERR_SYMBOL_OUT_OF_SCOPE		    = -136
FASMERR_USER_ERROR			    = -140

....then only the condition location was filled and the other ones not = zero.The description says...

;   When function returns FASM_ERROR, the error_code is filled with the
; code of specific error that happened and error_line is a pointer to the
; LINE_HEADER structure, providing information about the line that caused
; the error.

....but it keeps empty and I cant check the error what happens so error_code = 0 & error_line = 0.Why?How to get then the error code & error line?For example I used a asm code like this for testing it..

use32
mov eax,ecx
xor edi,asi

...only wrong letter.As return I get...

$ ==>    012A9CF0   FFFFFFFE  <--- condition = -2 FASM_ERROR same as in eax
$+4      012A9CF4   00000000  <--- error_code / output_length
$+8      012A9CF8   00000000  <--- error_line / output_data

...not sure why they both get not filled in a case of FASM_ERROR.Maybe anyone of you can tell me what the problem here is.In case of success FASM_ERROR all is filled right...

use32
mov eax,ecx
xor edi,esi

$ ==>    01359CF0   00000000 <--- FASM_OK
$+4      01359CF4   00000004 <---- output_length = 4
$+8      01359CF8   01359D80  bones.01359D80 <--- output_data
                                                  
$ ==>    01359D80     89C8     MOV EAX,ECX
$+2      01359D82     31F7     XOR EDI,ESI
$+4      01359D84     0000     ADD BYTE PTR DS:[EAX],AL

greetz

Link to comment

Hi guys,

ok today it works to get error codes into struct.Could be that the buffer I did used wasnt right from a top location that it failed strange on that way.Also have same trouble with VirtualQuery API if I use a memory struct location which is some random address which is odd and not even.Now it works if I use some odd location.

So I have another question about fasm.dll function fasm_Assemble.So is it also possible to set any syntax before a value / command which should NOT adjusted with the offset where I do assemble the code?

Example:

call 774ADB13h

gets assembled to

call 7B1ADEB3  ; 7B1ADEB3 - 774ADB13h = 03D003A0 VA = assemble start VA

So in my case I want it without to add the memory location

call 774ADB13h should get assembled same

...so I am looking for a headcode value syntax etc to tell the funcion not to change it also if its a call opcode.Does anyone know it coincidentally?

greetz

Link to comment

calls (e8 style) are relative to the va they're at e8 xx xx xx xx (where xxxxxxxx = signed / unsigned to show direction +/-2gb range) so its va + 5 (size of e8 xxxxxxxx opcode) +/- xxxxxxxx

so what you'd need is something like the ff 15 xx xx xx xx method, shell code style

call dword ptr [blah] ; syntax might be a wee bit different so experiment

jmp overblah

blah dd 774ADB13h

overblah:

 

Edited by evlncrn8
  • Like 1
Link to comment

Hi,

hmmm thats really bad.I wanted to get the same assembled what I did wrote same as MUA plugin does and now I got that problem with FASM.Great!Also if I use labels I get only the offsets value assembled.What can I do now?How to adjust assembled commands only using offset values after?

Problem: I can use FASM & DISASM or BEA Enigne.FASM is good to read my text I wrote + label handling and label holders (dd,dq,db etc) but disadvantage is I only get offsets value assembled not addresses I did use.No idea how to refix that after (pretty bump).DISASM can read my text as I did enter but I cant use labels or label holders I can use with FASM.With BEA I can only disassemble asm commands to text.Pretty bad.Are there some more alternativ libs / dlls etc I could try?

Maybe its possible to find location in FASM who sub the memory patch location from relativ commands to prevent that and getting the direct addresses assembled instead of offsets.Something like that maybe.If anyone has some more clues then just tell me so I stcuk at the moment.

Thanks

Link to comment

yep, for that sort of thing you need to code it like shell code, using delta's and such, i can do it in masm but im not sure about fasm as there's a lot of juggling about and a lot of mess

  • Like 1
Link to comment
8 hours ago, LCF-AT said:

hmmm thats really bad.I wanted to get the same assembled what I did wrote same as MUA plugin does and now I got that problem with FASM.Great!Also if I use labels I get only the offsets value assembled.What can I do now?

First, as evlncrn8 already explained, x86 jumps are relative to current EIP. Of all persons, you should know that. :) So, if you are assembling code, let's say, "jmp 12345678h", assembler must know the address where this jump will be located. Otherwise it can't calculate delta for the jump.

As a solution, try less whining and more reading manuals. Like this: https://flatassembler.net/docs.php?article=manual#2.2.4 

 

org and virtual directives can achieve the stuff you want. Org lets you set the address where the assembled code will be located in memory. Virtual lets you use magic labels to reference code that's not present in your ASM snippet.

Trivial example:

use32
org 1000h
call SomeStupidApi

virtual at 0BEEFh
 SomeStupidApi:
end virtual

will be assembled to 5 bytes

E8 EA AE 00 00

When you load those bytes at address 0x1000, it will disassemble as:

00001000: E8EAAE0000                     call         00000BEEF

 

And no, I didn't know this stuff 5 minutes ago. It's really all about RTFM.

  • Like 2
Link to comment

Hi guys,

ohhhh.That was good kao.Using org address  directive works as I wanted.Thats good now and with that I can work with go on.Thanks again for that tiny but effectiv information kao.I think more reading the manually is really my problem.Seems that I did just overfly that part before.

Thank you & Thumb Up :)

PS: What happens with the icons on this forum?They are no more comming if I just use the keyboard. :(

greetz

Link to comment

One more thing I need to ask.So I would like to use the if / else / end if statements and have some trouble with that.On the manual I can see a example like this..

    if count>0
        mov cx,count
        rep movsb
    end if

...now if I try that and it does only assemble the code without a compare (cmp command)!?Seems  that I dont understand this part too.How can I let assemble it with compare commands if I use if / else / end if etc?I mean similar as in MASM.I would like to check a register for example.

if eax = 0
nop
else if eax 5
nop
else
nop
end if

Is that also doable anyhow?

greetz

Link to comment

Hi,

About the absolute call

 In case of the value of EAX is not important (since in calling convention it doesn't have to be conserved)

mov eax,<some address>
call eax

or in case you need eax but you don't have parameters

push <some address>
call dword[esp]
add esp,4

or maybe for some reasons the above codes are incompatible and you don't want to use the @evlncrn8 method, you have this (I admit that the following code is ugly)

call caller
jmp next

caller:
push <some address>
ret

next:
...

 

About the conditions

in this link it's said that they are processed at compile time, i.e they select which code to compile under which condition (and not the code flow), therefore I don't think that there is a way to use a MASM like syntax,  only if maybe you write a function that converts the IFs to CMPs before passing the code to fasm_assemble (sounds complicated)

Edited by cob_258
grammar
  • Like 1
Link to comment

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