Hi, i write a simple dummy MASM program, like:
.386
.model flat, stdcall
option casemap:none
.data
szName db "MASM", 0
.code
start:
mov eax, DWORD PTR [szName]
ret
end start
But then when i use the OllyDbg to 'see' the code, i get:
Address Hex dump Command
00401005 /. /E9 06000000 JMP 00401010
0040100A | |CC INT3
0040100B | |CC INT3
0040100C | |CC INT3
0040100D | |CC INT3
0040100E | |CC INT3
0040100F | |CC INT3
<actual code starts here>
So as you can see there are 11 bytes that i have not written in my code. My question is which component (MASM, loader, other?) add this code to the executable? Why?
You must have caught a virus. I see only this:
CPU Disasm
Address Hex dump Command Comments
<ModuleEntryPoi Ú. A1 00204000 mov eax, [402000] ; ASCII "MASM"
00401005 À. C3 retn
00401006 00 db 00
Use a disassembler to get decent results.
.text:00401000 ;
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ; ¦ This file is generated by The Interactive Disassembler (IDA) ¦
.text:00401000 ; ¦ Copyright (c) 2002 by DataRescue sa/nv, <ida@datarescue.com> ¦
.text:00401000 ; ¦ Licensed to: Freeware version ¦
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ;
.text:00401000 ; File Name : H:\asm7\guro\guro.exe
.text:00401000 ; Format : Portable executable for IBM PC (PE)
.text:00401000 ; Section 1. (virtual address 00001000)
.text:00401000 ; Virtual size : 0000000B ( 11.)
.text:00401000 ; Section size in file : 00000200 ( 512.)
.text:00401000 ; Offset to raw data for section: 00000200
.text:00401000 ; Flags 60000020: Text Executable Readable
.text:00401000 ; Alignment : 16 bytes ?
.text:00401000
.text:00401000 model flat
.text:00401000
.text:00401000 ; ---------------------------------------------------------------------------
.text:00401000
.text:00401000 ; Segment type: Pure code
.text:00401000 _text segment para public 'CODE' use32
.text:00401000 assume cs:_text
.text:00401000 ;org 401000h
.text:00401000 assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00401000
.text:00401000 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401000
.text:00401000
.text:00401000 public start
.text:00401000 start proc near
.text:00401000 mov eax, dword_402000
.text:00401005 mov eax, offset dword_402000
.text:0040100A retn
.text:0040100A start endp
.text:0040100A
.text:0040100A ; ---------------------------------------------------------------------------
.text:0040100B align 200h
.text:0040100B _text ends
This should not be true (got a virus!) since every time i assemble+link a new executable i get this group of instruction in front of the actual instructions.
CPU Disasm
Address Hex dump Command Comments
00401004 CC INT3
00401005 /. E9 06000000 JMP 00401010
0040100A | CC INT3
0040100B | CC INT3
0040100C | CC INT3
0040100D | CC INT3
0040100E | CC INT3
0040100F | CC INT3
00401010 |> A1 00404000 MOV EAX,DWORD PTR DS:[404000] ; ASCII "MASM"
00401015 \. C3 RETN
00401016 A1 DB A1
00401017 90 NOP
00401018 1F DB 1F
What you suggest is that a virus has patch'ed the MASM assembler to add this 'stub' code in front of any newly created executable?? I don't say that is impossible (i don't know if it is possible either: ) but i don't think so...something else maybe happens here...any ideas?
Check your computer for a virus or trojan, if your binary code is being modified you have something wrong.
@hutch
You propose to use another debugger like IDA, and that the Ollydbg inserts the code to the executable ?
p.s: i have Windows XP SP3, and OllyDbg is version 2.00.
p.s.2: + i have sent the file to virustotal and it's clean!
p.s.3: I have downloaded the IDA Pro 5.0 Free version and i get the following output:
.text:00401000 ;
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ; ¦ This file is generated by The Interactive Disassembler (IDA) ¦
.text:00401000 ; ¦ Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com> ¦
.text:00401000 ; ¦ Licensed to: Freeware version ¦
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ;
.text:00401000 ; Input MD5 : 49BEB6B27558C787D89F615EECE5801A
.text:00401000
.text:00401000 ; File Name : C:\Documents and Settings\Giorgos\My Documents\Education Code\Assembly\Test\test.exe
.text:00401000 ; Format : Portable executable for 80386 (PE)
.text:00401000 ; Imagebase : 400000
.text:00401000 ; Section 1. (virtual address 00001000)
.text:00401000 ; Virtual size : 00001061 ( 4193.)
.text:00401000 ; Section size in file : 00001200 ( 4608.)
.text:00401000 ; Offset to raw data for section: 00000400
.text:00401000 ; Flags 60000020: Text Executable Readable
.text:00401000 ; Alignment : default
.text:00401000
.text:00401000 .686p
.text:00401000 .mmx
.text:00401000 .model flat
.text:00401000
.text:00401000 ; ---------------------------------------------------------------------------
.text:00401000
.text:00401000 ; Segment type: Pure code
.text:00401000 ; Segment permissions: Read/Execute
.text:00401000 _text segment para public 'CODE' use32
.text:00401000 assume cs:_text
.text:00401000 ;org 401000h
.text:00401000 assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00401000 dd 0CCCCCCCCh
.text:00401004 db 0CCh
.text:00401005 ; [00000005 BYTES: COLLAPSED FUNCTION start. PRESS KEYPAD "+" TO EXPAND]
.text:0040100A align 10h
.text:00401010
.text:00401010 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401010
.text:00401010
.text:00401010 _start proc near ; CODE XREF: startj
.text:00401010 mov eax, szName
.text:00401015 retn
.text:00401015 _start endp
.text:00401015
.text:00401015 ; ---------------------------------------------------------------------------
Ida is a disassembler and the result answers your question, entry point is 00401000 like normal. Remember that when you use a debugger as against a disassembler that a debugger must add debug code so it runs. The INT3's and JMP show the additional debug code.
hmm...but even the IDA disassembler 'finds out' the series of INT 3's (db CCh) instructions and at 00401005 contains this : [00000005 BYTES: COLLAPSED FUNCTION start. PRESS KEYPAD "+" TO EXPAND] which seems to me as a directive to generate a JMP +5 to current EIP to go to program entry start label. So it seems that OllyDbg does not introduce the extra 11 bytes to the executable, since IDA also finds this extra code. Does this mean that it's part of executable? Do you verify this?
What is missing is youur build data, both my own and others doing a normal release build get the correct start address, if you are getting debug code then you are doing a different build.
:U
I use the WinAsm Studio and when i change the build options to Release, i also get correct results! Just a last question, why in the debug version the jmp instruction is used?
they are just filler bytes - until the next aligned section, which is probably where the IAT is
Why someone wants to use as filler bytes the JMP instruction? i mean for the INT 3 instructions is more suitable to be used as filler bytes...Anyway, you said "until the next aligned section, which is probably where the IAT is", so do you think that after these 11 bytes (JMP+INT_3 x 6) the IAT is located?
not really sure - i have seen them before after ExitProcess and just assumed that's what i was seeing
they may be there for the debugger to trap on
NOP's would just let the debugger continue, of course
Quote from: guro on April 07, 2011, 01:55:41 PM
Why someone wants to use as filler bytes the JMP instruction?
Because 40000h that's where execution starts, so jmp must be the first instruction, otherwise the code would run into the int 3's and raise an exception.
Congrats that you got rid so quickly of your virus :bg
I have to admit that for a moment you terrified me :eek !! Thanks for helping guys, i'm coming from linux+nasm and i want to make the transition as quick as possible!
@dedndave
Regarding your statement about the location of IAT after the filler bytes, did you mean the 'filler' bytes i told (JMP+INT_3) ? Or something else? Because after the 'filler' bytes i told there is the start of the actual code, not the IAT right?
as i said - i have seen them AFTER ExitProcess :bg
what switches are you using to assemble and link ???
whiich version of MASM are you using ???
it looks like a debug side-effect
assemble: /c /coff /Cp /nologo /Fm /Zi /Zd
link: /SUBSYSTEM:WINDOWS /DEBUG /VERSION:4.0
predefined in WinAsm Studio, and yes they are used for DEBUG building, as i understood from this thread :bg
In this instance it looks like it's purely for alignment (see how the address is pushed forward to a 16 byte boundary.)
If the 'filler' required were only a few bytes, then you might see a single useless instruction in there to take up the required bytes, e.g. "mov edi,edi", but since it's more than a few, you get a string of NOPs with a jump over them.
You might also see this done at the beginning of functions, which seems entirely pointless - why not just place the entry to the function ON the aligned boundary and stop inserting these nonsense fillers? And the reason, particularly in debugging, is to allow for monitoring function calls to be patched into the beginning of functions without needing to do anything fancy (shifting memory around, breakpoint hacks, etc.)
@ Tedd
"You might also see this done at the beginning of functions, which seems entirely pointless"
The beginning is inside the function, not before right? (according at least to the example code or are you talking about a different situation?)
"why not just place the entry to the function ON the aligned boundary ... to allow for monitoring function calls to be patched into the beginning of functions without needing to do anything fancy ..."
Explain please the quoted statement further. As far as i understand, this 'stub' code (JMP[to reach actual code]+sequence of INT_3 instructions[for alignment]) is introduced at DEBUG assembler mode. Then the entry of the 'start' routine (according to the example) is located at dword-aligned boundary. If assembler is on RELEASE mode, then the stub code is omitted and first real instruction is placed again at dword-aligned boundary.
Quote from: guro on April 08, 2011, 12:47:05 PM
"You might also see this done at the beginning of functions, which seems entirely pointless"
The beginning is inside the function, not before right? (according at least to the example code or are you talking about a different situation?)
Yes, or there would be no need for the jump (it would never be excuted.)
Quote
"why not just place the entry to the function ON the aligned boundary ... to allow for monitoring function calls to be patched into the beginning of functions without needing to do anything fancy ..."
Explain please the quoted statement further. As far as i understand, this 'stub' code (JMP[to reach actual code]+sequence of INT_3 instructions[for alignment]) is introduced at DEBUG assembler mode. Then the entry of the 'start' routine (according to the example) is located at dword-aligned boundary. If assembler is on RELEASE mode, then the stub code is omitted and first real instruction is placed again at dword-aligned boundary.
In debug mode, yes; for use with a debugging monitor, performance analysis, or something similar.
In a release version, there shouldn't be any need since you assume your program is correct at that point.
Although in certain situations it may be done in release version to allow for run-time patching.