Author Topic: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets  (Read 36166 times)

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
I named these macro sets as Nasm PE macros, and their include file is "pe.inc". I have already made too much afford to make these set of macros happen. These macros uses bin file format output. It is flat binary. Macros fills in necessary headers.

Sample usage:

PE32

SECTION DATA

SECTION CODE
START
 instructions
END

But in order to go one step forward I need a few features from nasm which aren't develop yet (as far as I know).

Request 1:

First is I need to test if a label is defined before or after the current test  location. I need a preprocessor directive,  something like %iflabel  /  %endif.

Example 1:

label1:
    instructions....

    %iflabel label2
        do something
    %endif

label2:
    instructions....

%$label3:
    instructions....


Request 2:

I need to test if a single line macro defined after current line? %ifdef doesn't work in these situations.

Example 2:

%ifdef %$sometihng
   .... This isn't working
%endif


%assign %$something otherthings


Request 3:
I could get the last value of a single line macro (a %define statement). In order for me to fill in section table of pe file I need to know in advance how many sections are defined in pe file. I need to get last declared value of section number counter, each section increments the value by one.

Example 3:

; PE Section Header
; How to get last value of %$SECTION_COUNT???
; It is not even defined yet


%assign %$SECTION_COUNT 0

%$SECTION_1
%assign %$SECTION_COUNT %$SECTION_COUNT + 1

%$SECTION_2
%assign %$SECTION_COUNT %$SECTION_COUNT + 1


 





   

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #1 on: June 01, 2015, 06:38:36 AM »
I have nearly completed PE macro sets. As I mentioned earlier there are a few limitations of nasm. Because of that I can't produce more than one section in PE header. But that is not a big problem for me. I still can produce one section PE file. Resulting executable will have only one section. And will be smaller.

Because of that explicitly defining a SECTION isn't needed. So I will remove SECTION macro from future versions.

IMPORT and EXPORT macros are included and are ready. I am still working on RESOURCE macros.

There is example source codes you can find below. This is how source code of asm will look if you use PE macros.

In order to produce output,  use -f bin assembler switch.

Since labels in asm source code are offset based I had to invent VA() macro in order to turn offset based labels into virtual addresses. It is usualy linkers job but since we don't use linker in this project we have to manually turn offsets into VA's.

Example PE32 file:

%include "pe.inc"

; For 32-bit executable use PE32
; For 32-bit dll use DLL32
; 64-bit PE and DLL's are not ready yet
PE32

; Data declarations
Title db 'Title of MessageBox',0

; enty point of executable
START
; machine intructions
  ...
  push VA(Title)
  push 0
  call [VA(MessageBoxA)]

  LocalFunction:
     ...
     ret


; Setup import directory if you need to
IMPORT
  ; write down imported dll's
  LIB user32.dll
    ; write down imported functions
    FUNC MessageBoxA
  ENDIMPORT
 
  LIB kernel32.dll
    FUNC ExitProcess
    ...
  ENDLIB
ENDIMPORT

; Setup Export Directory if you need to
EXPORT
   ; write down local functions to export
   FUNC LocalFunction
   ...
ENDEXPORT


; Setup Resource Directory if you need to
RESOURCE
  ; I am working on details
ENDRESOURCE

END
; End of executable
« Last Edit: June 01, 2015, 06:49:56 AM by nalsakas »

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #2 on: June 07, 2015, 09:07:16 PM »
Although my work on RESOURCE directory macros continues, I have published pe macros on github. Anyone wants to give it a try link is here.

https://github.com/nalsakas/pe.git

With these macro sets one can produce PE32, DLL32 files with IMPORT and EXPORT directory support. RESOURCE directory currently supports only raw resources, user defined resources and MENU resources. MENU support recently added.

Example use of menus:

MENU menuname
    MENUITEM 'File', 101h

    POPUP 'Edit'
        MENUITEM 'Copy' ,200h
        MENUITEM 'Paste', 201h
    ENDPOPUP

    MENUITEM 'Help', 300h
ENDMENU
« Last Edit: June 07, 2015, 09:13:37 PM by nalsakas »

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #3 on: June 11, 2015, 06:29:46 PM »
#VERSION 0.2, 11/06/2015
- README file updated
- Sample applications added.
- EXPORT macro now needs a module name.
- Bugs cleared from EXPORT macro.

There was a bug in EXPORT macro. It is corrected.

EXPORT macro now needs export module name which is mandatory by pe format. User has to type filename here. I  was try to get file name from __FILE__ macro but it returns path too. So I removed default implementation.

3 sample code examples added to the project. One is simple MessageBox, other is simple window with menu, and last one is a simple DLL exports a function.

My work on DIALOG resource continues...

Get latest work here:
https://github.com/nalsakas/pe.git

Offline shaynox

  • Full Member
  • **
  • Posts: 118
  • Country: gr
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #4 on: June 11, 2015, 06:46:07 PM »
Wow, very interesting, I will use it certainly in future for a better of executable's system understanding and for more customizing x)

I'm a little noob in eng, so can you shortly describe what is VA/RVA ?
« Last Edit: June 11, 2015, 06:51:36 PM by shaynox »

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #5 on: June 12, 2015, 04:54:42 AM »
They are short for VA = Virtual Address and RVA = Relative Virtual Address. You can find these definitions in official/unofficial pe file format specifications.

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #6 on: June 15, 2015, 09:53:46 PM »
#VERSION 0.3, 16/06/2015
- README file updated
- Sample applications added.
- DIALOG resource added.
- STRINGTABLE resource added.
- Many control types added for DIALOG resource


With this version we can add DIALOG resource type to our executables. Sample usage is given below.


1) First we need to add DIALOG to the RESOURCE tree

RESOURCE
   TYPE RT_DIALOG
      ID ID_DIALOG
         LANG
            LEAF RVA(dialog), SIZEOF(dialog)
         ENDLANG
      ENDID 
   ENDTYPE
ENDRESOURCE

2) Next we define our DIALOG resource

; dialogs name/label is same as the one mentioned on LEAF node.
; x,y coordinates
; cx, cy are width and heights
DIALOG dialog, x, y, cx, cy
 
   ; Dialogs can have optional FONT, CAPTION, MENU, STYLE and EXSTYLE macros
   FONT size, 'font face'
   STYLE bitflags
   EXSTYLE bitflags
   MENU resource_id
   CAPTION 'text'

   ; Child controls
   CONTROL 'text', id, class_id, x, y, cx, cy, optional style, optional exstyle

   ; Predefined child controls doesn't have class_id
   PUSHBUTTON 'text', id, x, y, cx, cy, optional style, optional exstyle
   ...
ENDDIALOG


How to use STRINGTABLES?

1) Add stringtable to the resource tree as above.

2) Add stringtable as below

   STRINGTABLE label
      STRING 'First String'
      STRING "Second String"
   ENDSTRINGTABLE

3) Access strings from assembly code by using SID() macro. Short for string id.

   LoadString, hInst, SID(String Table Resource ID, Index of string in the table)

   SID(x,y) takes two parameter. First is ID of table defined in resource tree and other is string's index in table.


New sample applications are added to the project and old ones are updated.

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #7 on: June 17, 2015, 12:15:39 PM »
ACCELERATOR resource support added. Example application is added to the project.

USAGE: First include accelerator into resorce tree than add following definitions.

ACCELERATORTABLE accelerator
         
         ; %1 = ascii key or virtual key
         ; %2 = ID of key
         ; %3 = flags
   ACCELERATOR 'A', ID_ACTION_SHIFT_A, FSHIFT
   ACCELERATOR VK_F5, ID_ACTION_CONTROL_F5, FCONTROL | FVIRTKEY
   ACCELERATOR VK_RETURN, ID_ACTION_ALT_ENTER, FALT | FVIRTKEY
   
        ; default flag is shift key if not entered.
   ACCELERATOR 'H', IDM_FILE_HELP
ENDACCELERATORTABLE

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #8 on: July 02, 2015, 12:39:48 PM »
BITMAP resource support added.

With BITMAP macro you can include bitmaps into your resources. Then you can use them inside asm code with LoadBitmap API. To start with bitmaps first include an resource of type RT_BITMAP into resource tree. Than add file with BITMAP macro. Sample application is given in samples directory.

; %1 = label
; %2 = Bitmap file in string form

BITMAP bitmap1, 'bitmap.bmp'


Get the latest work is here:
https://github.com/nalsakas/pe

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #9 on: July 11, 2015, 11:09:15 AM »
64-bit support added.

Now you can use PE64 and DLL64. Sample applications are added. Project is 99% completed. I will work on ICON resources next.

Get the latest work from here: https://github.com/nalsakas/pe

Is there anyone using NASM PE MACROS out there?
« Last Edit: July 11, 2015, 01:14:56 PM by nalsakas »

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #10 on: July 17, 2015, 09:42:02 AM »
Because of the nature of icon file format and limitations of macros I may not add a support for icons. It can be made by hand though. But I couldn't find a proper way of handling icon file format.

Icon file format is a container for multiple images, such as bitmaps and pngs. Although icon file looks a single resource in rc scripts, all internal images gets expanded and take a different resource id in executable. Resource compiler makes that behind the scenes.

Maybe I will find a way someday but not today.

It can be done manually  by hand with the help of nasm's incbin directive. But it is tedious.

I wish nasm has had preprocessor version of incbin directive something like %incbin. Incbin runs at assemble time not at preprocessor time.

If I had preprocessor %incbin I could probably made ICON macros.

As of now I can say that development of NASM PE MACROS is finished.

Apart from bug fixes I don't plan to add any other feature.

Have a nice day
« Last Edit: July 17, 2015, 09:44:56 AM by nalsakas »

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #11 on: July 18, 2015, 09:40:09 AM »
FLAT MODEL

PE32, PE64, DLL32 and DLL64 macros now optionally excepts FLAT parameter. When it is used it removes the necessity of using VA() macro at labels. PE32 has optional third argument which is both section alignment and file alignment constant. If you don't supply anything it is 1000h.

After FLAT model your code looks simpler because all VA() references are removed. Downside is that in default 1000h file and section alignment your executable's size increases.

Code: [Select]
%include "../pe.inc"

PE32 FLAT

BYTE Title, "NASM PE MACROS",0
BYTE Text, "Flat memory works!",0

START
    push 0
    push Title
    push Text
    push 0
    call [MessageBoxA]
    ret

IMPORT
    LIB user32.dll
        FUNC MessageBoxA
    ENDLIB
ENDIMPORT

END
« Last Edit: July 18, 2015, 02:16:29 PM by nalsakas »

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #12 on: July 18, 2015, 07:23:34 PM »
64-bit support added.

Is there anyone using NASM PE MACROS out there?

Hi nalsakas, great work and interesting idea.

I'm testing 64-bit support.

64_dialogbox.asm:

I inserted new lines of code at the end of START procedure,
basically it should display a new message box when main window closes, BUT
instead of showing the new message box - the program terminates.

New lines of code, well this code is based on yours, only message box content is message box title.

Added an attachment of source files.
Encryptor256's Investigation \ Research Department.

Offline nalsakas

  • Jr. Member
  • *
  • Posts: 18
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #13 on: July 19, 2015, 09:12:39 AM »
Hi encryptor256,

Problem is not related to NASM PE MACROS but related to stack balancing. I am myself also new to 64-bit calling convention. I coudn't fully grasp the entire register based win64 calling convention. Although I found the cause and solution of the problem I don't know how to explain it. I've just added add esp, 40 at the beginning of MessageBoxA call.

Maybe someone here on forums can help us understand how win64 calling convention works :-) 

Code: [Select]

START
push rbp
mov rbp, rsp

; shadow stack area
sub rsp, 40   

; Get module handle
mov rcx, 0
call [VA(GetModuleHandleA)]
mov [VA(hIns)], rax

; DialogBox
mov r9, VA(DlgProc)
mov r8, 0
mov rdx, ID_DIALOG
mov rcx, [VA(hIns)]
call [VA(DialogBoxParamA)]

add rsp, 40 ;---> Addition

mov r9, 0
mov r8, VA(title)
mov rdx, VA(title)
mov rcx, 0
call [VA(MessageBoxA)]

.return:
mov rsp, rbp
pop rbp
ret

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Direct output to PE32, PE64, DLL32 and DLL64 with Macro Sets
« Reply #14 on: July 19, 2015, 09:31:40 AM »
Problem is not related to NASM PE MACROS but related to stack balancing.

Confirm! I already knew where the problem lies, I just wanted for you to struggle a bit.  :-X  ::)

Problem is here - incorrectly aligned stack according to your prolog setup.
So, according to your prolog setup routine should be (fixed):
Code: [Select]
        ; For START procedure and DlgProc too.
        ; ...
        ; shadow stack area
        ; sub rsp, 40 (NO)

sub rsp, 32 ; YES

        ; ...

Added attachment named: "64_dialogbox_new_new.asm".
I changed everywhere "sub rsp, 40" to "sub rsp, 32" and it works, now.

+ For later: If you call a procedure with more than four arguments, then stack shadow space should be increased appropriately too.
Encryptor256's Investigation \ Research Department.