PDA

View Full Version : Jump code Cave


jackall
April 13th, 2008, 11:29
i was making an attempt to inject code into a notepad exe file to display a MessageBox
I opened notepad.exe in OllyDbg. These are the first few lines of the code:

0100739D > $ 6A 70 PUSH 70
0100739F > 68 98180001 PUSH notepad.01001898
010073A4 . E8 BF010000 CALL notepad.01007568
010073A9 . 33DB XOR EBX,EBX
010073AB . 53 PUSH EBX ; /pModule => NULL
---------------------------------
Then an unconditional JMP to an address in code cave is executed.
JMP 01008780
--------------------------------
1-0100739D > /E9 DE130000 JMP notepad.01008780
2-010073A2 - |0001 ADD BYTE PTR DS:[ECX],AL
3-010073A4 . |E8 BF010000 CALL notepad.01007568

010073A9 . |33DB XOR EBX,EBX
010073AB . |53 PUSH EBX ; /pModule => NULL
-------------------------------
1-The first line shows that a jump is made to 01008780.
2-The 2nd line of code has changed .
3-This line and the rest continue unaffected .

what is this 2nd line 010073A2 |0001 ADD BYTE PTR DS:[ECX], AL means ?
could i get an explanation to the change from the previous to this new appearance ?

Thank you.

tHE mUTABLE
April 13th, 2008, 12:43
Come on... Just type "Inject code + Notepad" in Google, and you'll hit the first tutorial explaining all the details...

jackall
April 13th, 2008, 13:24
i was really not asking how to inject code into an exe. i was trying to understand the changes that took place when a LONG JMP is executed.

Thank you for your help.

GEEK
April 13th, 2008, 15:28
When you assemble the jmp instruction make sure you check the "Fill with nops" checkbox
the jmp instruction takes up more bytes that is the you see ADD BYTE PTR DS:[ECX] after it
instead if you do a "push 40" you wont see it

jackall
April 13th, 2008, 21:59
Well..GEEK !!

You explained it ...

Thank you..

xenakis
April 14th, 2008, 09:29
Funny, this is covered in the tutorial that was offered on the second post, at least if one actually reads past the title

jackall
April 14th, 2008, 13:18
The 2nd post directed me to this link http://home.inf.fh-rhein-sieg.de/~ikarim2s/how2injectcode/code_inject.html
i see the following lines in the tutorial :

" Because we're going to inject some code we've to have some space to inject it. In an EXE file are a lot of CodeCaves were nothing is done (DB 00). So lets scroll the CPU window a little bit down until you find a CodeCaves(look below)."

This ( Me..as a newbie understand ) refers to the requirement for space at the point where the code is going to be injected .

But what is happening at the point of origin of the jump ?
Why one line of code here is overwritten by another line ?
This is what i needed to understand .
and....
GEEK has given an explanation ..

More details associated to my query may be available in that tutorial …Somehow I missed it then.
i thank you for being helpful .

Regards.

personmans
April 14th, 2008, 15:32
Quote:
[Originally Posted by xenakis;73955]Funny, this is covered in the tutorial that was offered on the second post, at least if one actually reads past the title


To be fair, the tutorial only says "Press on Assemble and you will the the again the red marked(patched) code." Which is broken English and not a very in-depth explanation of what jackall was asking.

I know we encourage people to learn for themselves around here, but there are times when a little explanation helps, rather than hurts the learning process.

Personmans

jackall
April 15th, 2008, 00:26
.......You live and learn.......

tHE mUTABLE
April 15th, 2008, 01:08
This is not an excuse! What I mentioned in my first post, is just a hint for you so that in your future research will appreciate much more the Art of "Searching". I'm not taking your question about the subject as something bad to ask about... And I'm 100% if you do a a complete search you'll find a very informative explanation about that subject... And that's why the admins here keep emphasizing the importance of "Searching as a New Culture"... Do you know that there are good links at the home page...

jackall
April 15th, 2008, 05:37
Dear tHE mUTABLE …
I appreciate your reply...your hint to improve the art of searching . I will of course try to do that more in future . Probably these kinds of interactions make learning much lively and life more worthwhile.

Personmans was correctly guiding the proceeding in the right direction.

Regarding the title, ‘Jmp Code Cave ‘, I must admit that it was a bit extraneous to the query at the moment. Probably that title caused few redirections to Google.com.

Reflecting on the issue i make out a few reasons to include the word codecave.
i was not sure if there is any difference exists in a JMP to codecave from a JMP to other parts in the code. Additionally i had few more doubts that needed clarification when the jump reaches codecave.

Well ! if ever it reaches there …
Meanwhile....
It is a pleasure to learn in the company of people like Personmans and I truly appreciate your contribution in the context.

Regards..

xenakis
April 15th, 2008, 07:07
The part of the tutorial I was referring to was:
Quote:
You will see that there are a few lines overwritten! But this lines are needed to run the programm without errors. Identify the lines which get overwritten.

As I am sure you have learned by now, the act of jumping to a code cave does not magically change the code following the code. Your issue involves keeping track of bytes (and the number of bytes) overwritten when patching, that a jmp is involved is irrelevant. Perhaps had you looked at the machine code before and after your patch you would have figured it out yourself:
before
0100739D > $ 6A 70 PUSH 70
0100739F > 68 98180001PUSH notepad.01001898
010073A4 . E8 BF010000 CALL notepad.01007568
after
0100739D > /E9 DE130000 JMP notepad.01008780
010073A2 - |0001 ADD BYTE PTR DS:[ECX],AL
010073A4 . |E8 BF010000 CALL notepad.01007568

You can't put 5 bytes into 2 so your jmp spills over to the next instruction. When you code your cave, you would normally recode the overwritten code, so technically the "fill with nops" option is not really necessary (just cosmetic) since you would probably jmp back to 010073A4, placing the first two overwritten instructions to your code cave.

jackall
April 15th, 2008, 13:03
Thank you….xenakis

Basics are getting understandable …
Your explanation adds further clarity ….
and…
“Beauty is as beauty does! “

Jakor
April 21st, 2008, 15:08
ORIGINAL:

0100739D > $ 6A 70 PUSH 70
0100739F . 68 98180001 PUSH NOTEPAD.01001898
010073A4 . E8 BF010000 CALL NOTEPAD.01007568
010073A9 . 33DB XOR EBX,EBX
010073AB . 53 PUSH EBX ; /pModule => NULL
010073AC . 8B3D CC100001 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; |kernel32.GetModuleHandleA
010073B2 . FFD7 CALL EDI ; \GetModuleHandleA
010073B4 . 66:8138 4D5A CMP WORD PTR DS:[EAX],5A4D
010073B9 . 75 1F JNZ SHORT NOTEPAD.010073DA
010073BB . 8B48 3C MOV ECX,DWORD PTR DS:[EAX+3C]

YOUR'S (WITH NOP added in):


0100739D > $ 6A 70 PUSH 70
0100739F . 68 98180001 PUSH NOTEPAD.01001898
010073A4 . E8 BF010000 CALL NOTEPAD.01007568
010073A9 . 33DB XOR EBX,EBX
010073AB . 53 PUSH EBX ; /pModule => NULL
010073AC E9 CF130000 JMP NOTEPAD.01008780
010073B1 90 NOP
010073B2 . FFD7 CALL EDI ; \GetModuleHandleA
010073B4 . 66:8138 4D5A CMP WORD PTR DS:[EAX],5A4D
010073B9 . 75 1F JNZ SHORT NOTEPAD.010073DA
010073BB . 8B48 3C MOV ECX,DWORD PTR DS:[EAX+3C]


As you can see:
010073AC 8B3D CC100001 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; kernel32.GetModuleHandleA

has 6 bytes for the instruction. and a far jump always uses 5 bytes. This isn't really important as with a jump you will not automatically return to the instruction after the jump, so technically you don't have to make it a nop (though with a call also 5 bytes you would need to nop it).

The issue is you probably arn't keeping track of the stack during all of this. aka: you are making the jump inside of a set of instructions for a call.

instead place your jump at the beginning aka:


010073AB . 53 PUSH EBX ; /pModule => NULL
010073AC 8B3D CC100001 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; kernel32.GetModuleHandleA
010073B2 . FFD7 CALL EDI ; \GetModuleHandleA[/quote
should be:
[QUOTE]010073AB E8 D0130000 CALL NOTEPAD.01008780
010073B0 90 NOP
010073B1 90 NOP
010073B2 90 NOP
010073B3 90 NOP

and at 01008780 you should:


;Save Registers as needed (not eax)
;Do the stuff you want (aka)
push 0 ;MB_OK
push 0 ;TITLE = "Error"
push addr szText ; set this to an actual value for some text
push 0 ;Owner = Noone
call JMP.&user32.MessageBoxA
;Now return to notepad
;do overwritten code first
push 0
call JMP.&kernel32.GetModuleHandleA
;restore all saved registers
ret

jackall
April 23rd, 2008, 15:44
Yes jakor you are helpful ..

Right now I don’t have enough depth to grasp all you mentioned at a go. But I will …..learn... Line by line in time.

Meanwhile allow me to welcome your enthusiasm to share understanding with less privileged one's like me.

Thank you .
Regards

jackall
April 24th, 2008, 03:28
Quote:
[Originally Posted by Jakor;74115]ORIGINAL:
you are making the jump inside of a set of instructions for a call.

instead place your jump at the beginning aka:


Following your hint....

010073AB . 53 - - - - - - - - PUSH EBX ; /pModule => NULL
010073AC . 8B3D CC100001 -- MOV EDI, DWORD PTR DS :[<&KERNEL32.GetModu> ; |kernel32.GetModuleHandleA
010073B2 . FFD7 - - - - - - -CALL EDI ; \GetModuleHandleA

A JMP is executed at 010073AB ; it disturbed none and flew like a feather to the destination .as seen.

010073AC . 8B3D CC100001 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; |kernel32.GetModuleHandleA
010073B2 E9 C9130000 - - -JMP notepad.01008780
010073B7 90 NOP
010073B8 90 NOP

Meanwhile, little clarity on these few lines below would be much appreciated.

010073AB . 53 - - - - - - - - PUSH EBX ; /pModule => NULL
010073AC . 8B3D CC100001 - - MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; |kernel32.GetModuleHandleA
010073B2 FFD7 - - - - - - - - CALL EDI

1- There is a CALL at 010073B2 as seen above ..and
2- Is it not i.e. a JMP at 010073AB inside of a set of instructions for a call. ?
Quote:
[Originally Posted by Jakor;74115]ORIGINAL:
The issue is you probably arn't keeping track of the stack during all of this

3-And .to finish,. a little more light on the above account on Stack would be much appreciated...

Thank you.

blurcode
April 24th, 2008, 06:55
Code:

010073A9 /E9 D2130000 JMP 01008780 ; Go to our code
010073AE |90 NOP
010073AF |90 NOP
010073B0 |90 NOP
010073B1 |90 NOP
010073B2 |FFD7 CALL EDI ; ntdll.7C910738


Code:

01008780 6A 00 PUSH 0 ; Our code
01008782 68 50870001 PUSH 01008750 ; ASCII "Hello World!"
01008787 68 50870001 PUSH 01008750 ; ASCII "Hello World!"
0100878C 6A 00 PUSH 0
0100878E E8 6F7F447D CALL MessageBoxA
01008793 33DB XOR EBX,EBX ; Run original code
01008795 53 PUSH EBX
01008796 BF D1B6807C MOV EDI,GetModuleHandleA
0100879B ^ E9 12ECFFFF JMP 010073B2 ; Go back


Code:

01008750 . 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 ASCII "Hello World!",0


01008750 is the place I decided to put the data to use with MessageBoxA function.

About stack I think in every book about assembly all the info needed is inside the first chapter. Yes I am saying to open a book or search in Google for stack because the first result link ( http://en.wikipedia.org/wiki/Stack_(data_structure) ) explains it.

Jakor
April 24th, 2008, 14:05
I made these two patches to notepad.exe in ollydbg. I was wrong as i had a crash later when it tried calling GetModuleHandleA using edi again, so I just set edi in our patch. problem fixed.

Code:
010073AB E8 D0130000 CALL NOTEPAD.01008780 ; /pModule => NULL
010073B0 6A 00 PUSH 0

Code:
01008780 6A 00 PUSH 0
01008782 6A 00 PUSH 0
01008784 68 98870001 PUSH NOTEPAD.01008798 ; ASCII "Test MessageBoxA at Entry of Notepad.exe"
01008789 6A 00 PUSH 0
0100878B E8 FA7D447D CALL USER32.MessageBoxA
01008790 BF A1B6807C MOV EDI,kernel32.GetModuleHandleA
01008795 C3 RETN
01008796 90 NOP
01008797 90 NOP
01008798 54 PUSH ESP
01008799 65:73 74 JNB SHORT NOTEPAD.01008810 ; Superfluous prefix
0100879C 204D 65 AND BYTE PTR SS:[EBP+65],CL
0100879F 73 73 JNB SHORT NOTEPAD.01008814
010087A1 61 POPAD
010087A2 67:65:42 INC EDX ; Superfluous prefix
010087A5 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
010087A6 78 41 JS SHORT NOTEPAD.010087E9
010087A8 2061 74 AND BYTE PTR DS:[ECX+74],AH
010087AB 2045 6E AND BYTE PTR SS:[EBP+6E],AL
010087AE 74 72 JE SHORT NOTEPAD.01008822
010087B0 79 20 JNS SHORT NOTEPAD.010087D2
010087B2 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
010087B3 66:204E 6F AND BYTE PTR DS:[ESI+6F],CL
010087B7 74 65 JE SHORT NOTEPAD.0100881E
010087B9 70 61 JO SHORT NOTEPAD.0100881C
010087BB 64: PREFIX FS: ; Superfluous prefix
010087BC 2E: PREFIX CS: ; Superfluous prefix
010087BD 65:78 65 JS SHORT NOTEPAD.01008825 ; Superfluous prefix

jackall
April 24th, 2008, 22:30
Code:
After a placating JMP with a MessageBox, and when i try to run the file, i
often (not always) get this familiar souvenir..

" Notepad has encountered a problem and needs to close . We are sorry for the
inconvenience. ".

What could be the issue ?

Jakor
April 28th, 2008, 14:35
it's because my patches work off a call not a jump with a call you don't have to worry about return addresses.

But it might help if (since you are running this in olly, you would get the code it crashes on. how about a dump of the surrounding code, which module, and the registers and stack?

The little patches I have made I know will work 100% of the time.

jackall
May 4th, 2008, 08:52
Code:
Codecave is:
"A redirection of program execution to another location and then
returning back to the area where program execution had previously left."
By Drew_Benton in his article at http://www.codeproject.com/KB/cpp/codecave.aspx


While…
Code:
Procedure:
“The short block of instructions marked Procedure is a detour off the
main stream of instructions. At any point in the program you can duck
out into the procedure, perform its steps and tests, and then return
to the very place from which you left.”
–Jeff Duntemann in his book Assembly Language: Step-by-Step.

To my one-dimensional knowledge, both codecave and procedure look and sound almost similar.
Are they one in the same?
Or...
One and the same?

Regards...

naides
May 4th, 2008, 09:28
Quote:
[Originally Posted by jackall;74426][CODE]
To my one-dimensional knowledge, both codecave and procedure look and sound almost similar.
Are they one in the same?
Or...
One and the same?

Regards...


NO they are not.

When, in the process of reverse engineering, it is not enough to change a simple instruction or a constant, but what you want to do requires you add on a large series of instructions to a program that is already compiled, you cannot simply insert them as you would with a word processor in a piece of text. All the addresses, jumps, calls are relative, so inserting code changes the alignment, sends the program out of register and for sure screws up the the code flow.

To work around this problem, you have to find areas in the code segment that contain no useful data or code instructions: large patches of 0x00, or 0xCC or 0x90 that the compiler place in as stuffing to align the functions, which you can safely overwrite with your Add-on code.

Those un-used patches of repetitive bytes are called code caves.

A Procedure or subprogram is a coding device that interrupt the linear flow of a program, jump to a different area in the code and perform some useful work, perhaps returning a result.
Procedures are usually coded at high level, before the program is compiled.

Codecaves and procedures are not completely unrelated though. In fact once you place your add-on code in a codecave, you actually need to treat the add-on as a "procedure": you need to direct the code flow towards your add-on code in the cave (using a jump or a call instruction), save any thing that is important(registers, stack frame), perform your dastardly deeds, restore any thing of any value for the normal program execution, then go back to the instruction right following the one you used to take your detour from the original code flow (using a jump or a ret instruction).

Hope this is not too confusing.

Jakor
May 5th, 2008, 15:23
Simple:
a procedure is a clump of code. a code cave is where a clump of code *may* go. Procedure gets it's name from higher level programing.

Extra:
code caves may be "created" by looking at the PE Header and figuring out a section whos Read/Write/Execute Priviledges are sufficient, as well as having a virtual size less than a physical size. Thus creating extra room in the exe which will never be used. Then by placing your code after the virtual size in the physical section and by changing the size of the virtual size in the Header. But at this point, you must remember that we would be working with RVA's not offsets.

More:
When writting an addon, just write a loader/injector and use a dll.

jackall
May 7th, 2008, 03:06
Thank you naides.. Thank you jakor..

Your illumination on Codecaves and procedures are informative, constructive
and most important ....comprehensible.

Regards …

Jakor
May 8th, 2008, 20:53
You're welcome when / if you have questions on dll injecting come and find me again. I check here as often as possible, but the forums in my signature is also available to reach me (I check it very often)