Is there a way to create the '.idata' section automatically? Privalov, you must have put some thought into this. :) IMHO, idata should be created programmatically, but I very much like the way it is exposed to the programmer. Here is my brief thought:

1. create a string in the stdcall macro consisting of all the function names
2. have include files for each DLL to test the created string for including .idata

This sounds like it would slow assembly time down, and I'm curious of what others might have in mind? This feature could be added to the assembler output routine, but then it is hidden from the programmer - not good. This is why I'd like to find a good way to add this feature with macros.
Posted on 2002-07-18 05:39:24 by bitRAKE
Hi!

If you create a file where you have

ShortName;ApiName;dll

MessageBox;MessageBoxA;user32.dll

you could probably parse it with a Macro.
But it isn't such hard to generate the section with the "import" macro.

Also generating by hand, without the "import" macro is easy (from pedemo.asm):



section '.idata' import data readable writeable

dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0

kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0
user_table:
MessageBox dd RVA _MessageBoxA
dd 0

kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0

_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
Posted on 2002-07-18 06:10:22 by bazik
Try to think of a much larger program bAZiK. :tongue: I don't want to manage adding and subtracting idata when this could be created by a DLL interface definition (important to have this, imo) and use of that interface.

I would also like to begin UNICODE support at this level.
Posted on 2002-07-18 07:07:39 by bitRAKE
For a larger programm I would write a PowerBASIC programm for generation of the '.idata' section :)
Posted on 2002-07-18 09:21:29 by bazik
Yes, that was an option I concidered. Additionally, this problem exposes other limitations of FASM. I would like to see the macro language of FASM powerful enough to handle this, as it would provide functionality for other problems as well. :) Another solution would be to allow FASM to execute assembled code during the assembly process! :eek: Using something like virtual code pieces. This would allow the assembler to be scriptable in assembler.
Posted on 2002-07-18 09:44:58 by bitRAKE
Since I still have to explore the macro features, maybe someone could create a parser of an assembly file that will determine the functions used and the corresponding data for the .idata section? Just an idea though.
Posted on 2002-07-18 11:09:24 by stryker
stryker, this is done by the assembler at assemble-time -- may as well add the feature there. Unless you want to write a parser? ;)
Posted on 2002-07-18 11:11:52 by bitRAKE
But we don't wanna wait this thing to be added do we? Might as well create a separate parser and just copy and paste it to the .asm file and assemble it. :)
Posted on 2002-07-18 11:14:33 by stryker

But we don't wanna wait this thing to be added do we?
You have the source code, why wait? :tongue:

Just patch at CALL instruction and SECTION directive.
Posted on 2002-07-18 11:36:35 by bitRAKE
Oh yeah!!!, I'm dumb. :( :grin:

You know, I actually did started coding for the parser. :tongue:

What was I thinking....

I don't want to mess around and give out the executable. Who knows, there could be bugs in the revised program and I don't want to screw up... Maybe for my personal use, I could but ...
Posted on 2002-07-18 11:38:21 by stryker
I'll see what I can do and maybe post some code.
Something like:
call MessageBoxA@USER32.DLL
jmp ExitProcess@KERNEL32.DLL
Posted on 2002-07-18 12:14:22 by bitRAKE
bitRAKE,
wich language has the domain extension ".dll" ?
This reminds me on opening a redirector & email service :)
Posted on 2002-07-18 12:44:19 by bazik
No domain is .DLL, afaik. Maybe a different syntax would be better?
Posted on 2002-07-18 13:15:48 by bitRAKE
It needs only few changes to macros (but it will surely dramatically slow down assembly process). First change to invoke macro in stdcall.inc file:



macro invoke proc,[arg]
{ common
invoked equ invoked,proc
if ~ arg eq
stdcall [proc],arg
else
call [proc]
end if }


Second, changes to library and import macros in import.inc:



macro library [name,string]
{ forward
local _label
if name#. <> -1
dd 0,0,0,RVA _label,RVA name
end if
common
dd 0,0,0,0,0
forward
if name#. <> -1
_label db string,0
end if }

macro import name,[label,string]
{ common
name:
forward
if label in <invoked>
local _label
label dd RVA _label
end if
common
name#. = $ - name - 1
if $ > name
dd 0
end if
forward
if label in <invoked>
_label dw 0
db string,0
end if }


The label for import macro should now follow the macro name, before function names.

These macros will produce entries in import section only for functions that have been at least once
invoked inside the program. So you can make a common list of all libraries and functions you can
use and include it with every program.

Please try compiling the following example with those modified macros and look at the output '.idata':




format PE GUI 4.0
entry start

include 'include\kernel.inc'
include 'include\user.inc'

include 'include\macro\stdcall.inc'
include 'include\macro\import.inc'

section '.data' data readable writeable

caption db "Win32 Assembly",0
message db "Hi! I'm general protection exception!",0

section '.code' code readable executable

start:

invoke MessageBox,0,message,caption,MB_OK
invoke ExitProcess,0

section '.idata' import data readable writeable

library kernel,'KERNEL32.DLL',\
user,'USER32.DLL',\
shell,'SHELL32.DLL',\
advapi,'ADVAPI32.DLL'

import kernel,\
GetModuleHandle,'GetModuleHandleA',\
GetCommandLine,'GetCommandLineA',\
LoadLibrary,'LoadLibraryA',\
FreeLibrary,'FreeLibrary',\
VirtualAlloc,'VirtualAlloc',\
VirtualFree,'VirtualFree',\
CreateFile,'CreateFileA',\
GetFileSize,'GetFileSize',\
ReadFile,'ReadFile',\
WriteFile,'WriteFile',\
CloseHandle,'CloseHandle',\
SetCurrentDirectory,'SetCurrentDirectoryA',\
CreatePipe,'CreatePipe',\
DuplicateHandle,'DuplicateHandle',\
GetCurrentProcess,'GetCurrentProcess',\
CreateProcess,'CreateProcessA',\
GetExitCodeProcess,'GetExitCodeProcess',\
ExitProcess,'ExitProcess'

import user,\
RegisterClass,'RegisterClassA',\
CreateWindowEx,'CreateWindowExA',\
DefFrameProc,'DefFrameProcA',\
DefMDIChildProc,'DefMDIChildProcA',\
GetWindowLong,'GetWindowLongA',\
SetWindowLong,'SetWindowLongA',\
MoveWindow,'MoveWindow',\
UpdateWindow,'UpdateWindow',\
GetMessage,'GetMessageA',\
TranslateMessage,'TranslateMessage',\
TranslateMDISysAccel,'TranslateMDISysAccel',\
TranslateAccelerator,'TranslateAcceleratorA',\
DispatchMessage,'DispatchMessageA',\
SendMessage,'SendMessageA',\
LoadCursor,'LoadCursorA',\
LoadIcon,'LoadIconA',\
LoadMenu,'LoadMenuA',\
GetSubMenu,'GetSubMenu',\
CheckMenuItem,'CheckMenuItem',\
EnableMenuItem,'EnableMenuItem',\
LoadAccelerators,'LoadAcceleratorsA',\
GetClientRect,'GetClientRect',\
GetWindowRect,'GetWindowRect',\
GetSystemMetrics,'GetSystemMetrics',\
GetWindowPlacement,'GetWindowPlacement',\
SetWindowPlacement,'SetWindowPlacement',\
SetFocus,'SetFocus',\
SetCursor,'SetCursor',\
MessageBox,'MessageBoxA',\
wvsprintf,'wvsprintfA',\
DialogBoxParam,'DialogBoxParamA',\
GetDlgItem,'GetDlgItem',\
GetDlgItemInt,'GetDlgItemInt',\
SetDlgItemText,'SetDlgItemTextA',\
GetDlgItemText,'GetDlgItemTextA',\
SendDlgItemMessage,'SendDlgItemMessageA',\
CheckDlgButton,'CheckDlgButton',\
IsDlgButtonChecked,'IsDlgButtonChecked',\
EnableWindow,'EnableWindow',\
EndDialog,'EndDialog',\
InvalidateRect,'InvalidateRect',\
WinHelp,'WinHelpA',\
PostQuitMessage,'PostQuitMessage'

import shell,\
DragAcceptFiles,'DragAcceptFiles',\
DragQueryFile,'DragQueryFile',\
DragFinish,'DragFinish',\
Shell_NotifyIcon,'Shell_NotifyIcon'

import advapi,\
RegCreateKeyEx,'RegCreateKeyExA',\
RegOpenKeyEx,'RegOpenKeyExA',\
RegSetValueEx,'RegSetValueExA',\
RegQueryValueEx,'RegQueryValueExA',\
RegCloseKey,'RegCloseKey'

Posted on 2002-07-18 15:14:27 by Tomasz Grysztar
Thanks Privalov, that is exactly what I meant. :alright:
How might Unicode support be added? Another IF statement in import?
Posted on 2002-07-18 15:26:52 by bitRAKE
:eek: :eek: :eek:

WOW! :alright:



Imp Addr Hint Import Name from KERNEL32.DLL - Not Bound
-------- ---- ---------------------------------------------------------------
00003054 0 ExitProcess

Imp Addr Hint Import Name from USER32.DLL - Not Bound
-------- ---- ---------------------------------------------------------------
0000306A 0 MessageBoxA

Disassembly

00402000 start:
00402000 6A00 push 0
00402002 6800104000 push 401000h
00402007 680F104000 push 40100Fh
0040200C 6A00 push 0
0040200E FF156A304000 call dword ptr [MessageBoxA]
00402014 6A00 push 0
00402016 FF1554304000 call dword ptr [ExitProcess]

Posted on 2002-07-18 15:38:54 by bazik
Oh shoot...Should I ditch my parser?

cool macro BTW :alright:
Posted on 2002-07-18 15:45:22 by stryker

Thanks Privalov, that is exactly what I meant. :alright:
How might Unicode support be added? Another IF statement in import?


Why bloat the macro more?

Just make a "API_A.inc" and "API_U.inc" :tongue:
Posted on 2002-07-18 15:56:43 by bazik
AFternoon, All.

hmmmm...interesting....

Just made those changes, and then slapped everything from:
section '.idata' import data readable writeable
and onwards, into it's own .inc file

It means that the idata section could be made universal, and just included with every proggy at the end of each file?

Cheers,
Scronty
Posted on 2002-07-22 06:44:32 by Scronty


It means that the idata section could be made universal, and just included with every proggy at the end of each file?


Yes :)

But I may use the "standard" form for posting code on this Forum, because not everyone will use this macros :)
Posted on 2002-07-22 07:23:07 by bazik