flat assembler
Message board for the users of flat assembler.

Index > Windows > Manual PE with macros ;)

Author
Thread Post new topic Reply to topic
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 16 Jun 2009, 02:00
I got bored one day some weeks ago, and looked through some Fasm examples when I encountered DOS386's manual PE (also known as "format binary as .EXE") (it's not official, it's found here).

Then I liked the idea a lot, to have much more low-level control, but it seemed pretty hardcoded: offsets and sections were hardcoded to given numbers (in sections case, just 1 section). While this may be ok for some apps, I'm always a planning type of dude so I thought, why not use Fasm's powerful macro capabilities to make it easy to change things? (like offsets and/or add sections).

This is a good example for those who would like to learn Fasm's powerful macro capabilities, though it isn't very clear I warn you -- you'll have to be somewhat proficient in Fasm's macros to understand it. But don't worry -- you don't have to understand it if you want to simply add a section or change some offsets because that's incredibly easy right now with them!

I think I'm gonna write all my small asm apps with this method cause I know all the junk produced Very Happy

Thanks goes to DOS386 for providing the base because PE is a beast to handle by default (not to mention, bloated) Confused

(see attachment for it, there are 3 files)

Two are asm examples, one with a section for everything, the second with a section for code&data and one for imports, the differences between them is very small! Wink)

The last one is a .txt file I saved from various sources over the net regarding the attributes/characteristics of a section, you'll need it if you'd like to modify them.

By the way this is only for console but it's easy to do it for GUI, just change the relevant value somewhere and use GUI APIs Very Happy

If there are any bugs, which I hope there aren't, please report them. (I tested it and it worked, it also has an 'error checking' mechanism in the macros themselves).


EDIT: Maybe it would've been better if I posted this in Main so all users can look at the macros?


Description: Doing the PE format the "manual" way with Fasm :D
Download
Filename: Fasm Manual PE.zip
Filesize: 9.02 KB
Downloaded: 683 Time(s)


_________________
Previously known as The_Grey_Beast


Last edited by Borsuc on 21 Jun 2009, 16:17; edited 2 times in total
Post 16 Jun 2009, 02:00
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 16 Jun 2009, 11:13
I had deliberately posted it in Main since it works in DOS also Wink Now I updated my post (not the attach, though).
Post 16 Jun 2009, 11:13
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 16 Jun 2009, 16:31
DOS386 wrote:
I had deliberately posted it in Main since it works in DOS also Wink Now I updated my post (not the attach, though).
Yeah I kinda figured that out after I posted it lol Very Happy

Anyway please download the new much improved version (same attachment, updated).

It has much more elegant error control (I mean, so you don't type something bad in macros accidentally), you can edit the DOS message (for those that want) and it will automatically pad/change the MZ header to account for that. Plus it is more optimized when calculating the file offset: it simply overrides the 'org' directive to store the offset in the file of the last org. So to compute the file offset of the current position, you can do (in the macro, 'fileoffset' is local variable only, but you can easily get it out -- I didn't want it to interfere with normal variables though):
Code:
OFFSET = fileoffset + $-$$    
which is what it already does which is much better right now.

Also, you can define a section's attributes MUCH easier and clearer without comments:

Code:
section table main, '.program', attributes: readable, writeable, executable, contains code    
(uses 'match' and irp Smile)
Of course you can still enter a manual DWORD value, if that's what you want. The available attributes in 'english' are written in the "section attributes.txt" (it was renamed so deleted the old one, not needed).

Also added few more variables to make it easier to change stuff.
All you need to change are the variables at the beginning (if you want them different). If you add a section, all you'll need to do is add, first, the RVA of the memory location where you want it loaded (has to be aligned to 'ccsectionalign'). The variable should be named
Quote:
ccnamerva
where 'name' is the name of the section (it has nothing to do with the one you store in the PE file, this one is only for Fasm!)

Then, put it in the section table like this:
Code:
section table name, '.PEname', attributes: readable, writeable, etc...    
'name' is the name used before, the 8-char-max string '.PEname' is the name/ID used in the PE, and the attributes were explained before.

Then just put
Code:
section name    
where you want it to begin in your code. You do not have to 'end' it before starting another section, that happens automatically.

However you will have to end the LAST section like this:
Code:
section end    
(therefore, you can't name your sections 'table' or 'end' cause those are special).

Example:

Code:
ccmainrva = 0x00001000
ccsectionrva = 0x00002000

[...]

section table main, '.program', attributes: readable, writeable, executable, contains code
section table section, '.section', attributes: readable, writeable, has initialized data

[...]

section main

[...]

section section

[...]

section end    
That's all Very Happy

_________________
Previously known as The_Grey_Beast
Post 16 Jun 2009, 16:31
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 21 Jun 2009, 16:18
Updated, very few tweaks. Now it outputs 'exe' instead of 'bin' extension. Also "filealign" is 100% correct with any setting right now. Wink
Post 21 Jun 2009, 16:18
View user's profile Send private message Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36 01 Jul 2009, 04:51
Thank you for your hardwork! This is very good quality work indeed. I've only tried to code a PE manually once a few years back and failed miserably. Your code is very well commented and I will definately keep it as a reference. The added import section makes this way of coding a program workable. Thanks again!
Post 01 Jul 2009, 04:51
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 01 Jul 2009, 13:56
Cheers. If you want you can even change the DOS stub message (e.g: make it specific for your app). You can make it very long also, larger than a DOS page, that is calculated.

(any bugs, please report, but I hope there aren't any).
Post 01 Jul 2009, 13:56
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 29 Aug 2009, 20:13
UPDATE

Here's a new version. Now it works with uninitialized sections properly (it uses 'virtual' for those sections automatically so, if you put any data in such section, it won't matter at all! you don't have to use 'rb' and such).

I had to remove the "manually input section flags" because with that method I have no control in macros over the 'uninitialized' attribute, unfortunately. So you'll have to use the descriptive macros like "has uninitialized data" and such (there's an example).

The console_2section.asm has two sections, the second one is with uninitialized data (it has no purpose whatsoever but to make you get the idea Wink). The first one is identical to the console.asm's section.


Description: Updated version that works with uninitialized sections automatically, also with 'org' inside 'virtual' directives properly!
Download
Filename: Fasm Manual PE.zip
Filesize: 10.09 KB
Downloaded: 638 Time(s)


_________________
Previously known as The_Grey_Beast


Last edited by Borsuc on 30 Aug 2009, 14:20; edited 1 time in total
Post 29 Aug 2009, 20:13
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 30 Aug 2009, 14:18
Sorry, yet again another small update

This isn't a bugfix or anything, it's just that if you used "org" inside 'virtual' you would have got a wrong fileoffset. This fixes that. Hope it's the last version Laughing

(download the previous attachment again, if you have previously downloaded -- it's a small addition at the beginning of the macros overriding the "virtual" directive)
Post 30 Aug 2009, 14:18
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 03 Sep 2009, 19:32
I'm curious. How do the outputted binaries hold up against false positives?
Post 03 Sep 2009, 19:32
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 03 Sep 2009, 23:06
Not sure, and don't care. To be honest I don't think it would signal anything, it depends how you use (I guess if you have self-modifying code and data in one section, it would trigger). But no one said you have to make only one section.

_________________
Previously known as The_Grey_Beast
Post 03 Sep 2009, 23:06
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 04 Sep 2009, 00:01
Well, the main reason i ask is because i'm looking to manual PE because "format PE" is known for FPs (not sure exactly why). Anyway, i'll have to try it sometime. Keep up the good work.
Post 04 Sep 2009, 00:01
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 04 Sep 2009, 00:04
Off-topic from the macro's, but shows why FASMs "format PE" has so many false positives:



kohlrak wrote:
Blah Blah Blah......(not sure exactly why).....Blah Blah Bleh


I believe FASM stores its version number in the header, and that may mess with some virus scanners. OR, it could be because of the missing stuff in the header.

EDIT: Found it. This thread.

I agree about code and data values, I plan to have such change (thought a bit different in implementation) - however why would I want to give up storing fasm's version in PE header, just like I should be allowed to?


EDIT: Must be the missing stuff from the header.
I made the necessary changes to FASM(as mentioned in that thread) and recompiled the "Star Trek" game(the one with 11 reports on VirusTotal). Now look at its VirusTotal scan report. HUGE REDUCTION in false positives! From 11/41 scanners reporting it as a virus to 2/41! So, if you don't want FP's, just make those changes that are mentioned in the thread I linked.

_________________
----> * <---- My star, won HERE


Last edited by windwakr on 04 Sep 2009, 03:00; edited 1 time in total
Post 04 Sep 2009, 00:04
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 04 Sep 2009, 01:37
Borsuc wrote:
Not sure, and don't care. To be honest I don't think it would signal anything, it depends how you use (I guess if you have self-modifying code and data in one section, it would trigger). But no one said you have to make only one section.
Eh.. everything I make in FASM does some JITy stuff like that at startup, but no false positives from any of the scanners on virustotal. o_O
I think they come from something else. Probably the way format PE makes the header by default.
Post 04 Sep 2009, 01:37
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 04 Sep 2009, 15:17
hmm, virus scanners are stupid? why would they check the innocent header? Confused
Post 04 Sep 2009, 15:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20486
Location: In your JS exploiting you and your system
revolution 04 Sep 2009, 15:22
Borsuc wrote:
hmm, virus scanners are stupid? why would they check the innocent header? Confused
Because (some) virus writers like to use custom headers. Most AVs take the path of "if it is in any way out of the ordinary then mark as malware".
Post 04 Sep 2009, 15:22
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 04 Sep 2009, 15:25
revolution wrote:
Borsuc wrote:
hmm, virus scanners are stupid? why would they check the innocent header? Confused
Because (some) virus writers like to use custom headers. Most AVs take the path of "if it is in any way out of the ordinary then mark as malware".
Thing is, the vast majority of malware is made in languages like C/C++ and VB. Custom headers are generally a sign of the demoscene. Sad
Post 04 Sep 2009, 15:25
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.