Log in

View Full Version : Reversing our own tool: HexWorkShop


ZaiRoN
November 28th, 2002, 16:25
Hi All!

What do you thing about an 'adding funcionality project'?
HexWorkShop is a nice hex editor with many features but not totally oriented to RE. With this project, we will try to make this target a little more RE like . I have in mind two different project but for now we will work on the first one.

Our mission is to modify the 'Goto' dialog box.
I don't know if you use this tool but -like many others- after you have opened a file, you can jump from a byte to another using a simple dialog box named 'Goto' (Ctrl-G to access the dialog). I often use this feature to locate the byte(s) to patch but the problem is that you have to provide the offset you want to reach. exempli causa: if you have to patch the byte at VA=403020 you have to find the offset relative to that VA and then insert it; this is very nasty because you have to use an FLC or a disassembler to discover the offset.
What I want to do is to modify the dialog and let it accept also Virtual Address value. Basically, the only thing we have to do is to perform the conversion from Virtual Address to Offset and then call the usual goto_function.

I think we can split this project in various tasks:
1. Find the WndProc relative to the dialog 'Goto' and try to understand how the program handles various messages received by the dialog
2. Figure out how to do the conversion from Virtual Address to Offset
3. Add the new choice_button to the dialog
4. Add the new code

OK, I think it's time to begin with the first task!

To retrieve the WndProc you might work in two different ways.
To perfom the jump, the program reads the value you put in the edit box, so breaking on something like GetDlgItemText function could show you the way.
Another way might be to use the WinHelp function (is called when you click on the 'Help' button); I often use this function when it's possible because I think it's an easy way to find the WndProc(and maybe because I readed it on an old Neural Noise's great tutorial )

Please, let me know what do you think about the project and/or if you want to change something.

regards,
ZaiRoN

lamer__
November 28th, 2002, 18:19
somehow hw doesnt work correctly for me...it doesnt save...

r4g3
November 28th, 2002, 20:02
2. Figure out how to do the conversion from Virtual Address to Offset

uhm are you going to read the PE header for that ? (is there any other way ?) that would make a hell lot of asm coding...

nikolatesla20
November 28th, 2002, 21:11
Hmm. Pretty cool idea.

Yes, you would have to read in the PE header to do this, but that isn't really all that hard. You can quickly verify it's a PE with a few simple functions. Plus you should be able to just tack this code on the end of Hex Workshop in a new section.

Come to think of it, this would be a pretty nice feature. I get sick of having to use a seperate program for File locations...

Only thing is, I use old Hex Workshop, not the new ones. So even if I did it , it wouldn't be compatible with others

HINT on finding the WinProc: Usually I just start the program up and then use my Visual C++ tools (Spy++) and drop the crosshair on the window and click OK. It will then tell you the address of the WndProc. Simple as that.


-nt20

ZaiRoN
November 28th, 2002, 21:26
Hi r4g3/nikola,

Quote:
uhm are you going to read the PE header for that ?
Yes, it should be necessary.

Quote:
Yes, you would have to read in the PE header to do this, but that isn't really all that hard.
These are the ideas I had to solve this problem:
- you can retrieve the informations you need when the file is loaded
- the file loaded is mapped somewhere in memory and you can retrieve informations from there

This 2° task could be done in many ways, and like nikola said: 'Come to think of it' and to decide which is the best!

>I use old Hex Workshop
Download my version

Let me know

regards,
ZaiRoN

Kayaker
November 29th, 2002, 04:26
Excellent idea Zairon. I always grumble at having to disassemble a file with WDasm or whatever just to get a hex offset to use with the Hexworks GoTo feature. The resource dialog for GoTo looks accessible in a resource editor, so it should be easy to resize it and add another edit box and button or something. The file you open is already mapped into memory by HW itself and if you break on MapViewOfFile you can find a few places where you could put in a small patch to transfer the returned starting address of the mapped view into your own variable.

You could type in your VA, convert it to an offset and then programmatically transfer the result into the original HW offset edit control and it's ready to go. Here's a snippet I use in code for VA to Offset conversion, maybe it can help. If you were reading the VA from your own edit control you could probably convert it to a dword value with GetDlgItemInt, then you just pass it to this proc.

Code:

pPE_MapView DWORD ? ; starting address of the mapped view
Address DWORD ? ; VA Address

invoke VAToOffset, Address

;===============VAToOffset proc=====================
VAToOffset PROC uses edi esi edx ecx VAWORD

mov esi, pPE_MapView

assume esitr IMAGE_DOS_HEADER ; MZ
add esi, [esi].e_lfanew ; MZ + 3Ch
assume esitr IMAGE_NT_HEADERS ; PE
mov edi, VA ; edi == Linear Virtual Address
sub edi, [esi].OptionalHeader.ImageBase ; Linear VA - ImageBase = RVA

;--------------------------------
; If address selected is outside of program code,
; RVA will be < 0 or greater than Image Size

mov eax, [esi].OptionalHeader.SizeOfImage ; SizeOfImage
.if edi < 0 || edi > eax
ERROR MESSAGE
mov eax, 0
ret
.endif

;-------------------------------

mov edx, esi
add edx, sizeof IMAGE_NT_HEADERS ; PE + F8 = Start of SectionHeaders
mov cx, [esi].FileHeader.NumberOfSections ; NumberOfSections counter in ECX
movzx ecx, cx

assume edxtr IMAGE_SECTION_HEADER
.WHILE ecx>0 ; check all sections

.if edi>=[edx].VirtualAddress
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData

.if edi<eax ; address is in this section
mov eax,[edx].VirtualAddress
sub edi,eax
; edi == difference between specified RVA and section's RVA
mov eax,[edx].PointerToRawData
add eax,edi ; eax == FILE OFFSET
ret
.endif
.endif

add edx,sizeof IMAGE_SECTION_HEADER ; go to next section
dec ecx

.ENDW

assume edx:nothing
assume esi:nothing

VAToOffset endp
;===============End VAToOffset proc=================

COMMENT %
IMAGE_FILE_HEADER STRUCT
Machine WORD ?
NumberOfSections WORD ?
TimeDateStamp DWORD ?
PointerToSymbolTable DWORD ?
NumberOfSymbols DWORD ?
SizeOfOptionalHeader WORD ?
Characteristics WORD ?
IMAGE_FILE_HEADER ENDS

IMAGE_NT_HEADERS STRUCT
Signature DWORD ?
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

IMAGE_SECTION_HEADER STRUCT PE + F8 = Start of SectionHeaders
Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?)
union Misc
PhysicalAddress dd ?
VirtualSize dd ?
ends
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
IMAGE_SECTION_HEADER ENDS
%


Waiting for the fun to begin...

Kayaker

ZaiRoN
November 29th, 2002, 19:59
Hi friends!
There is sufficiently enthusiasm to make a very good work :-) thx Kayaker for the snippet!

Today I worked a little on the program.
The program is not packed and is written with visual c++ (and use mfc; gr...!) so I suggest you to use IDA to study the program.

task 1:
I tried to understand where the WndProc is located and how messages are handled. I have to admit that I am not totally confident with mfc and -please- correct me if I made something wrong or if there's an easy way to solve the problem.
With mfc based programs, I usually use the AfxFindMessageEntry function to retrieve where messages are checked. Use IDA search function to locate this function.
Every message received in this function has this structure:

struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code (or WM_NOTIFY code)
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};

The most important value is the last, pfn. This is the address of the routine that manage this particular message.
In every mfc based program, AfxFindMessageEntry has the same scheme.
Code:
:004945D1 push ebp
:004945D2 mov ebp, esp
:004945D4 push ebx
:004945D5 mov ebx, [ebp+arg_0] ; ebx points to our AFX_MSGMAP_ENTRY
:004945D8 mov eax, [ebp+arg_4] ; windows message received by the dialog
:004945DB mov edx, [ebp+arg_8] ; control code
:004945DE mov ecx, [ebp+arg_C] ; control ID
:004945E1 cmp dword ptr [ebx+10h], 0 ; this is the first instruction of the *while*
; that looks in the message_map for our message
:004945E5 jz short loc_494604 ; no message is founded
:004945E7 cmp eax, [ebx] ; ebx points to our AFX_MSGMAP_ENTRY structure
:004945E9 jz short loc_4945F0 ; jump if the message is founded
:004945EB add ebx, 18h ; moves to the next message in the messagemap
:004945EE jmp short loc_4945E1
:004945F0 cmp edx, [ebx+4]
:004945F3 jnz short loc_4945EB
:004945F5 cmp ecx, [ebx+8]
:004945F8 jb short loc_4945EB
:004945FA cmp ecx, [ebx+0Ch]
:004945FD ja short loc_4945EB
:004945FF mov [ebp+arg_0], ebx ; save the AFX_MSGMAP_ENTRY relative to the message received
:00494602 jmp short loc_494609
:00494604 xor eax, eax
:00494606 mov [ebp+arg_0], eax
:00494609 mov eax, [ebp+arg_0]
:0049460C pop ebx
:0049460D pop ebp
:0049460E retn 10h

Obviously, this function is called many times so a conditional breakpoint is needed ;-)
Following this scheme, I have found where Go_button_message is handled; take a look at the 'pfn' parameter in the structure pointed by ebx @4945FF.

Now that we know this information, - theoretically - we can read (if is present!) the VA from the new edit box, convert it and then pass it to offset to the offset edit box

ZaiRoN

Kayaker
November 30th, 2002, 14:42
That's really good information you gave there Zairon. It makes getting a handle (sorry) on the MFC message handling routines a lot easier. Definitely clarifies what at first appears to be a mess. I'll outline a bit of what I did if it might help as a guide for anyone considering trying this.

I decided to sacrifice the Help button as a Convert button (who the hell needs a help button on the Goto dialog anyway?) This way the original Go button function is untouched.

What I did first was to get the CtrlID of the Help button (047E) from WDasm and set a conditional breakpoint with it on the last cmp before the AFX_MSGMAP_ENTRY is saved. When the help button is clicked it will break there after all the checks are done and the code is about to go to the specific Help routine.
:004945DE mov ecx, [ebp+arg_C] ; control ID
...
:004945FA cmp ecx, [ebx+0Ch]

BPX 4945FA if (EBX->0C) == 47E

A little tracing and you find the Help routine here:

:00412674 mov eax, 004B4347
:00412679 call 00446BF0 ; Set up SEH
:0041267E
...
buncha gargage
...
:004126D4 Call WinHelpA
:004126DA jmp 0041270D ; Restore SEH

I decided to leave the existing SEH handler in place and create the main patch jump at 0041267E, and return to 0041270D which would exit gracefully.


Once again I decided to use Snippet Creator, and is really the best way considering how much code the entire patch took. To start with though, the first thing you need is the return value from MapViewOfFile that Hexworks uses to map the target file into memory. Setting a bp on that API you find it's called 3 times, the 3rd one being the charm.

:00410FC3 Call MapViewOfFile ; return value is the starting address of the mapped view
:00410FC9 cmp eax, edi
:00410FCB mov dword ptr [esi+10], eax
:00410FCE je 00410FDF
:00410FD0 push edi

I decided to create the first patch at 00410FCE, all you're simply doing is saving the value in eax to your own variable. What I found was the easiest was to do this patch *first* and note the ABSOLUTE value of the address it's saved to. Then in the 2nd patch with the main VA to Offset conversion you access the absolute address directly. You do this first patch on the *original* HW file, then use this patched version as the file for the *2nd* patch. By doing this patch first you don't disturb the absolute address of your saved variable and you can make all the changes you want in your main patch without losing the reference.

Here's how I set up the first patch in Snippet Creator:
Choose 'Patch as New Section'
Choose 'Redirect Control From Code Section' and use VA 410FCE
Choose 'Return To Program' and use VA 410FD0
Choose 'Restore Overwritten Instruction'

The patch itself is simply:

-----------------
dummyvariable DWORD ? ; starting address of the mapped view

.code
mov dummyvariable, eax
------------------

Now, you will need to trace into this patch and note down the Absolute address the mapped view is stored in by Snippet Creator, for me it was 520020h. Now you can create the 2nd patch using this address as the start of the MZ header for your conversion routine.


As mentioned above I chose 0041267E as a redirect address and 0041270D as the return VA for the 2nd patch, but I chose not to restore the overwritten instructions since they were all within the useless Help file routine anyway.

I won't spoil it by posting all my code but I will mention a few things. If you haven't used Snippet Creator before, you write your patch with all the normal Masm (or Tasm) syntax, plus includes and proc declarations. However, instead of using the .data and .data? directives it's best to simply list all your data variables at the start of the patch and jump over them to the beginning of the code section. If you do use the directives, SC will assemble and patch the file OK, but the data variables will be compiled in a section that isn't mapped into virtual memory. I found this out by crashing and checking with a PE editor that something doesn't work quite right if you do this.

So instead just do something like:

Includes and Proc declarations
jmp @F
...
Data variables
...
@@:
.code

You may not need the .code declaration but I found it was necessary if you use any ASSUME directives.


OK, one more thing. How to find the hWnd of the Edit control and main dialog box?

Hints:

GetMessagePos function returns a long value that gives the cursor position in screen coordinates. This position is the point occupied by the cursor when the last message retrieved by the GetMessage function occurred.
i.e. when you click the mouse on the Help button (could also use GetCursorPos)

WindowFromPoint function retrieves the handle of the window that contains the specified point.

GetParent function retrieves the handle of the specified child window's parent window.

Between this and the CtrlIDs you've got all you need to access the edit control or anything else in Hexworks.

Cheers,
Kayaker

ZaiRoN
December 1st, 2002, 16:27
I'm back.

Hi Kayaker,
very nice work!

I have finished the project in a little bit different way from you.

I'm testing this new version at the moment but maybe you are interested in how I solved the problem.
The guidelines that Kayaker gave us is fine and the use of CodeSnippetCreator is perfect.

First of all, I haven't sacrificed the *poor* Help button :-).
I added a new label "Virtual Address:" and, of course, a new edit box for the virtual address. I have used resource hacker for doing the job.

Like you said, 'the first thing you need is the return value from MapViewOfFile that Hexworks uses to map the target file into memory'. I have also perform a check to see if the file loaded has a valid PE format. This, mainly because if the file has not a PE format I will disable the VirtualAddress's edit box. The check is very simple and is based on the keyword "MZ" and "PE". Obviously, this feature is not necessary but...hey, It's a funny game :-)

After that, I have had to add the code for the conversion. I added the new code directly in the beginning of the Goto routine . In particular, I maked a jump to my code at 4940FA. The new code perform these operations
- retrieve the handle of the VA editbox and get the VA value
- the VA value is converted in offset using your procedure
- retrieve the handle of the Offset editbox and put the new offset inside
- return to the original code that perform the jump to the new byte

How have I found the various handle?
Forced by your solution, you have used the correct and general way to find the handles; instead of, I have used a more practical method studying the original Goto routine. Infact, the program reads the offset using GetDlgItemText function in this way:

:00494118 push eax ; lpString
:00494119 push dword ptr [esi+1Ch] ; hWnd
:0049411C call ds:GetWindowTextA

'dword ptr [esi+1Ch]' is the handle of the dialog we were looking for
Then, I used GetDlgItem function to retrieve control's handles.
That's all.

Quote:
Here's how I set up the first patch in Snippet Creator:
Choose 'Restore Overwritten Instruction'

hmmm, correct me if I'm wrong but in this way you save the mapped address only for the first file loaded !?!

Quote:
You may not need the .code declaration but I found it was necessary if you use any ASSUME directives.

eheh, weird thing! In my code I use ASSUME directives without .code declaration. The .code keyword is putted in the file .asm by CodeSnippetCreator (look at the asm file that he generates) so why you need to redefine it ?

Like Kayaker said, pushed by the enthusiasm, maybe we have gone too fast; this is not a tutorial and many parts have not been explained so if you have any questions don't hesitate to ask! The project is definitely not very easy, and involved many fundamental concepts and things that you will use many times.

Well, now it's really all.

cheers,
ZaiRoN

ps. Is someone interested in a 'Reversing our own tool: HexWorkShop v3.11' part #2 ?

ZaiRoN
December 2nd, 2002, 18:35
Hi Kayaker,

I'm trying to make hws work with several open files and seems to be a hell; this characteristic it is not really necessary and the old one was working correctly but this would make the project much interesting and complete.
Have you tried?

I found that the program save a sort of structure for each of the opened files where it puts all the necessary informations. Unfortunately I can't say which are exactly these informations but I am almost sure that there is the address where the file is mapped (bpx on UnMapViewOfFile and close a file; you'll see how the program retrieves the right map address).
This information is very useful because we could avoid the first patch and to work directly with the structure memorize and the handle of the active MDI child (wm_mdigetactive to retrieve the handle of the active MDI child).

Unfortunately, I have some problem to find how/where the program save this data(s); any hint ? :-)

ZaiRoN

Kayaker
December 3rd, 2002, 06:48
You may be onto something there Zairon. It appears that when HW opens a second and subsequent file it unmaps the current one after copying the mapped view into another allocated memory location. This is actually quite wise, it keeps a local copy for itself while freeing up any memory Windows may want to use to map files. I thought it might be using a linked list of sorts to keep track of its local copies of mapped files, but I can't find a 'linked' list per se. Maybe it's just using a table reference somewhere.

There IS evidence of how it stores the important pointers. I opened several files and took note of the value of ESI and what values were added to that area after the files were mapped i.e:

:00410FC3 Call MapViewOfFile
:00410FC9 cmp eax, edi
:00410FCB mov dword ptr [esi+10], eax ; store starting address of the mapped view
...
:00410FD4 Call GetFilesize
:00410FDA mov dword ptr [esi+1C], eax ; store file size


Now, after opening several files I did a search for each of the values of ESI (which are just random stack values). I was looking for evidence of a linked list, i.e. a small array which might keep a few important values such as the mapped address and file name or size, *PLUS* an offset to another small array which tracked a different file, etc. Well I found each of the small arrays but didn't see evidence of linking between them. There might another linked list or maybe simply a table somewhere to each of the small arrays, but I haven't found it.

If you want to check out what I mean, break on MapViewOfFile and note the value of ESI and the API return value and the file size for 3 or 4 files. Then do a hex search in memory for each of the ESI values in turn. When you find it in stack memory, scroll the data window up a line or two and you should also see the corresponding file size and the address of the new LOCAL copy of the mapped file which was copied to a lower memory region before being unmapped to make way for the current file. Only the last file opened will be in high memory.

If HW indeed does unmap files as new ones are opened then you are quite right that this is the proper way to go, else we can never be sure the mapped address saved in the first patch will be correct after a while. If you're only opening one file it doesn't matter, but there's no guarantee a second file opening won't overwrite part of the first mapped region.

btw, you were right about not needing the .code directive, it just seemed to solve a problem at the time but obviously isn't required, and you were also right about setting the restore overwritten instruction option makes the patch only valid for one file. Hopefully your new approach will solve that ;-)

Kayaker

Zero
December 3rd, 2002, 07:54
Quote:
Reversing our own tool: HWS v3.11

This remembers me that HWS 4.0 should be released this december.

Zero

nikolatesla20
December 3rd, 2002, 18:25
If HW uses MFC, it no doubt might use the document/view architecture for its MDI handling.

If so, the "document" is independent of the "view" , or window. It gets really messy and that might be why its hard to really track down how the current file mapping is stored, but it would definitely be in a collection of instances somewhere. (you have an array of pointers to objects, and then the mapping variable is an offset into that object)

-nt20

ZaiRoN
December 6th, 2002, 19:11
Hi All.

(maybe) I have found a way to solve the problem and I need your help...

At first, following the right suggestion made by nikola, I studied how mdi childs were opened and how/where important values were stored; useless say that I lost my self in the jungle of the program's instructions (if you want to try, 'bpx createwindowex' or catch wm_mdicreate message) So, I took another way: the Goto procedure. Yes, her! The fact is that inside this function, the program has to know all the informations about the file that has the current focus; this is the reason why I started from here.

All the work starts from 4940FA. The most important value you have to take care is stored in esi; in fact, if you look at the code of this routine you will find many values referenced by [esi+xx]. esi is the address of a big table (or a structure if you prefer) that contains many (and mostly unknown) values. I will call Table1 this structure.

[Table1+6Ch] points to Table2
[Table2+3Ch] points to Table3
[Table3+6Ch] points to the address where the file is mapped from.

From what I have seen, Table3 seems have many values related to the current file, and I think is the place where the program stores informations of it; unfortunately, I'm not able to give a specific meaning to the tables.

All the work is done from sice using the search function to locate the various bytes in memory and ... of course: guessing! This is the reason why I need your help. Are you able to locate the right address with this method? If so, we can finally complete this project, otherwise...gr!

ZaiRoN

mike
January 7th, 2003, 03:48
If only they had used eclipse--then this job would have been trivial.

www.eclipse.org

[yAtEs]
February 10th, 2003, 11:57
check out version 4s structure system,
http://www.hexworkshop.com/structure_viewer.gif
super :-p

yates.

ZaiRoN
February 10th, 2003, 14:22
Hi [yAtEs],
I have not tryed yet this new release but this feature seems to be quite interesting.
I have written a structure to recognize PE file.
Tell me if is there something wrong in it :-)

ZaiRoN

Kayaker
February 10th, 2003, 15:35
That is a pretty cool feature indeed I tried your PE structure plugin ZaiRoN and it seems to work quite well. One thing I can't quite figure out though is why the Value field of the Structure Viewer defaults to decimal or how to change it to hex. There must be a way to define a DWORD variable as hex?

Actually, your plugin and others would be a great teaching aid to understanding the structure of the PE file. Besides being useful as sort of a visual aid, pointing out where these structures reside and what they actually look like in a hex editor, the knowledge might help wean some people from relying on automagic PE fixer-upper tools so much...

Kayaker

ZaiRoN
February 20th, 2003, 19:16
Hi all,

I have finally solved the old problem, the new version of HWS (I have used v4.00, you can do the same thing with the old version) works with an arbitrary number of opened files. I am still testing and optimizing this new feature but everything seems to be ok.
I was thinking to write a tutorial when I will be sure that everything works fine; I am very busy in these days and it will take me many days. In the meanwhile, I will give you a little description of my new approach.

I have to admit that due to the nature of the program and the incapacity of mine, I have used a non-elegant way to solve the problem.
The idea behind my new approach is related with the handle of the various MDI child windows opened.
For each file opened, I save a simple structure containing the handle of the MDI child window (the window that shows the file's bytes) and some values necessary for the conversion from VA to Offset. In this way we don't need anymore to know where the file is mapped to the memory.
I will use this data when the user decides to jump in VA.
How the program can recognize which is the right structure to be used? I mean, the jump option is for the current focused file so we need to find the right structure of this file. This is done recognizing the focused MDI child window (which is the window where the jump will be performed). In particular, retrieving the handle of the window; to retrieve this handle, you only need to send a WM_MDIGETACTIVE message. I use this handle like a key in a database that is used to retrieve data; in this case, the data represents the values used to perform the conversion from VA to Offset.

The idea is simple and also the new code is very simple. I will not give you any snippet for the moment because, as I said before, my snippet(s) are not definitive.
Btw, I am here for any suggestions, comments and/or something else ;-)

ZaiRoN

ZaiRoN
June 2nd, 2003, 15:31
Hi All,
after some months, I have finally found the time to write the tutorial. You can find it at:
http://www.woodmann.com/fravia/Zai_HwsRev_eng.htm
If you want, you can post your comments/critiques/improvements/etc here.

Regards,
ZaiRoN

LOUZEW
December 5th, 2004, 16:08
Hi, Zairon
i'm certainly a bit late to work on this app but after reading your tut, i find it so great ! and i want to RE this app too, like a new challenge for me.
Your tut is quite interesting, i'm working on 4.2 version of HWS.

In your tut you tell us to include a "HWS4.INC" file in the project, can you please, tell me where i can find this Inc file ? ?

Thank's

ZaiRoN
December 5th, 2004, 18:16
Hi.
It is not never too much late :-)

HWS4.INC:
Code:

HANDLE TYPEDEF DWORD
NULL equ 0
WM_SETTEXT equ 0Ch
WM_MDIGETACTIVE equ 229h

;---------------------------------------------
BM_SETCHECK equ 0F1h
BST_CHECKED equ 1

;---------------------------------------------
wsprintfA PROTO C WORD,:VARARG
wsprintf equ <wsprintfA>

;---------------------------------------------
INFOFILE STRUCT
handleMDI DWORD ?
imageBase DWORD ?
nSections WORD ?
INFOFILE ENDS

SECTIONVALUES STRUCT
virtualOffset DWORD ?
rawOffset DWORD ?
pointerToRawData DWORD ?
SECTIONVALUES ENDS

;------------------------------------------------------------------
IMAGE_NUMBEROF_DIRECTORY_ENTRIES equ 16
IMAGE_SIZEOF_SHORT_NAME equ 8
IMAGE_DOS_SIGNATURE equ 5A4Dh
IMAGE_NT_SIGNATURE equ 00004550h

IMAGE_FILE_HEADER STRUCT
Machine WORD ?
NumberOfSections WORD ?
TimeDateStamp DWORD ?
PointerToSymbolTable DWORD ?
NumberOfSymbols DWORD ?
SizeOfOptionalHeader WORD ?
Characteristics WORD ?
IMAGE_FILE_HEADER ENDS

IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD ?
isize DWORD ?
IMAGE_DATA_DIRECTORY ENDS

IMAGE_OPTIONAL_HEADER32 STRUCT
Magic WORD ?
MajorLinkerVersion BYTE ?
MinorLinkerVersion BYTE ?
SizeOfCode DWORD ?
SizeOfInitializedData DWORD ?
SizeOfUninitializedData DWORD ?
AddressOfEntryPoint DWORD ?
BaseOfCode DWORD ?
BaseOfData DWORD ?
ImageBase DWORD ?
SectionAlignment DWORD ?
FileAlignment DWORD ?
MajorOperatingSystemVersion WORD ?
MinorOperatingSystemVersion WORD ?
MajorImageVersion WORD ?
MinorImageVersion WORD ?
MajorSubsystemVersion WORD ?
MinorSubsystemVersion WORD ?
Win32VersionValue DWORD ?
SizeOfImage DWORD ?
SizeOfHeaders DWORD ?
CheckSum DWORD ?
Subsystem WORD ?
DllCharacteristics WORD ?
SizeOfStackReserve DWORD ?
SizeOfStackCommit DWORD ?
SizeOfHeapReserve DWORD ?
SizeOfHeapCommit DWORD ?
LoaderFlags DWORD ?
NumberOfRvaAndSizes DWORD ?
DataDirectory IMAGE_DATA_DIRECTORY
IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>
IMAGE_OPTIONAL_HEADER32 ENDS

IMAGE_NT_HEADERS STRUCT
Signature DWORD ?
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

IMAGE_DOS_HEADER STRUCT
e_magic WORD ?
e_cblp WORD ?
e_cp WORD ?
e_crlc WORD ?
e_cparhdr WORD ?
e_minalloc WORD ?
e_maxalloc WORD ?
e_ss WORD ?
e_sp WORD ?
e_csum WORD ?
e_ip WORD ?
e_cs WORD ?
e_lfarlc WORD ?
e_ovno WORD ?
e_res WORD 4 dup(?)
e_oemid WORD ?
e_oeminfo WORD ?
e_res2 WORD 10 dup(?)
e_lfanew DWORD ?
IMAGE_DOS_HEADER ENDS

IMAGE_SECTION_HEADER STRUCT
Name1 db
IMAGE_SIZEOF_SHORT_NAME dup(?)
union Misc
PhysicalAddress dd ?
VirtualSize dd ?
ends
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
IMAGE_SECTION_HEADER ENDS

shaddar
December 6th, 2004, 09:31
404 Zairon!!
Could you upload that again, or send me via PM?

Woah, this is 2003 stuff. Never noticed this Thread
Well, anyway, the 404 is real

thx for PM!

homersux
December 6th, 2004, 12:45
Hey, maybe it's easier to send an email to HW author to request this feature?

LOUZEW
December 6th, 2004, 13:38
Many thank's Zairon for this INC file, i can now progress in my study.
That job is exactly what i like to do !

LOUZEW
December 8th, 2004, 15:35
Code:
DataDirectory IMAGE_DATA_DIRECTORY
HWS4.inc(79) : error A2008: syntax error : in structure

IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>
HWS4.inc(80) : error A2008: syntax error : IMAGE_NUMBEROF_DIRECTORY_ENTRIES

Name1 db
HWS4.inc(112) : error A2008: syntax error : in directive

IMAGE_SIZEOF_SHORT_NAME dup(?)
HWS4.inc(113) : error A2008: syntax error : dup

Microsoft (R) Incremental Linker Version 5.12.8078


Am I missing anything ? Maybe an option to set in MASM (i'm using MASM8)

ZaiRoN
December 9th, 2004, 07:10
I have no problem here. I used Code Snippet Creator leaving the original settings for masm (I changed the path directory only...)