Log in

View Full Version : Code Injection


Hoof Arted
June 17th, 2002, 17:00
Hi, I am trying to get to grips with injecting code / functions into an application and I have a few questions for those who know...

The code below is basically the same executable but the first lot of code does not have the MessageBoxA function at 00401070, in the second

disassembly. Now with the scene set, Please go below for my questions.

00401000 >/$ 6A 00 PUSH 0 ; /pModule = NULL
00401002 |. E8 85000000 CALL <JMP.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA
00401007 |. A3 80304000 MOV DWORD PTR DS:[403080],EAX
0040100C |. E8 93000000 CALL <JMP.&COMCTL32.#17> ; [InitCommonControls
00401011 |. 6A 00 PUSH 0 ; /lParam = NULL
00401013 |. 68 2E104000 PUSH testreme.0040102E ; |DlgProc = testreme.0040102E
00401018 |. 6A 00 PUSH 0 ; |hOwner = NULL
0040101A |. 6A 65 PUSH 65 ; |pTemplate = 65
0040101C |. FF35 80304000 PUSH DWORD PTR DS:[403080] ; |hInst = NULL
00401022 |. E8 6B000000 CALL <JMP.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401027 |. 6A 00 PUSH 0 ; /ExitCode = 0
00401029 |. E8 58000000 CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess
0040102E |. 55 PUSH EBP
0040102F |. 8BEC MOV EBP,ESP
00401031 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00401034 |. 3D 10010000 CMP EAX,110
00401039 |. 75 02 JNZ SHORT testreme.0040103D
0040103B |. EB 40 JMP SHORT testreme.0040107D
0040103D |> 3D 11010000 CMP EAX,111
00401042 |. 75 1F JNZ SHORT testreme.00401063
00401044 |. 817D 10 EA0300>CMP DWORD PTR SS:[EBP+10],3EA
0040104B |. 75 30 JNZ SHORT testreme.0040107D
0040104D |. 6A 20 PUSH 20 ; /Count = 20 (32.)
0040104F |. 68 00304000 PUSH testreme.00403000 ; |Buffer = testreme.00403000
00401054 |. 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
00401059 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040105C |. E8 3D000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
00401061 |. EB 1A JMP SHORT testreme.0040107D
00401063 |> 83F8 10 CMP EAX,10
00401066 |. 75 0C JNZ SHORT testreme.00401074
00401068 |. 6A 00 PUSH 0 ; /Result = 0
0040106A |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040106D |. E8 26000000 CALL <JMP.&USER32.EndDialog> ; \EndDialog
00401072 |. EB 09 JMP SHORT testreme.0040107D
00401074 |> B8 00000000 MOV EAX,0
00401079 |. C9 LEAVE
0040107A |. C2 1000 RETN 10
0040107D |> B8 01000000 MOV EAX,1
00401082 |. C9 LEAVE
00401083 \. C2 1000 RETN 10
00401086 $-FF25 08204000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; KERNEL32.ExitProcess
0040108C $-FF25 0C204000 JMP DWORD PTR DS:[<&KERNEL32.GetModuleHa>; KERNEL32.GetModuleHandleA
00401092 $-FF25 18204000 JMP DWORD PTR DS:[<&USER32.DialogBoxPara>; USER32.DialogBoxParamA
00401098 $-FF25 1C204000 JMP DWORD PTR DS:[<&USER32.EndDialog>] ; USER32.EndDialog
0040109E $-FF25 14204000 JMP DWORD PTR DS:[<&USER32.GetDlgItemTex>; USER32.GetDlgItemTextA
004010A4 $-FF25 00204000 JMP DWORD PTR DS:[<&COMCTL32.#17>] ; COMCTL32.InitCommonControls
004010AA 00 DB 00
004010AB 00 DB 00
004010AC 00 DB 00


00401000 >/$ 6A 00 PUSH 0 ; /pModule = NULL
00401002 |. E8 99000000 CALL <JMP.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA
00401007 |. A3 80304000 MOV DWORD PTR DS:[403080],EAX
0040100C |. E8 AD000000 CALL <JMP.&COMCTL32.#17> ; [InitCommonControls
00401011 |. 6A 00 PUSH 0 ; /lParam = NULL
00401013 |. 68 2E104000 PUSH testreme.0040102E ; |DlgProc = testreme.0040102E
00401018 |. 6A 00 PUSH 0 ; |hOwner = NULL
0040101A |. 6A 65 PUSH 65 ; |pTemplate = 65
0040101C |. FF35 80304000 PUSH DWORD PTR DS:[403080] ; |hInst = NULL
00401022 |. E8 7F000000 CALL <JMP.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401027 |. 6A 00 PUSH 0 ; /ExitCode = 0
00401029 |. E8 6C000000 CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess
0040102E |. 55 PUSH EBP
0040102F |. 8BEC MOV EBP,ESP
00401031 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00401034 |. 3D 10010000 CMP EAX,110
00401039 |. 75 02 JNZ SHORT testreme.0040103D
0040103B |. EB 54 JMP SHORT testreme.00401091
0040103D |> 3D 11010000 CMP EAX,111
00401042 |. 75 33 JNZ SHORT testreme.00401077
00401044 |. 817D 10 EA0300>CMP DWORD PTR SS:[EBP+10],3EA
0040104B |. 75 44 JNZ SHORT testreme.00401091
0040104D |. 6A 20 PUSH 20 ; /Count = 20 (32.)
0040104F |. 68 00304000 PUSH testreme.00403000 ; |Buffer = testreme.00403000
00401054 |. 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
00401059 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040105C |. E8 51000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
00401061 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401063 |. 68 00304000 PUSH testreme.00403000 ; |Title = ""
00401068 |. 68 00304000 PUSH testreme.00403000 ; |Text = ""
0040106D |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401070 |. E8 43000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401075 |. EB 1A JMP SHORT testreme.00401091
00401077 |> 83F8 10 CMP EAX,10
0040107A |. 75 0C JNZ SHORT testreme.00401088
0040107C |. 6A 00 PUSH 0 ; /Result = 0
0040107E |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401081 |. E8 26000000 CALL <JMP.&USER32.EndDialog> ; \EndDialog
00401086 |. EB 09 JMP SHORT testreme.00401091
00401088 |> B8 00000000 MOV EAX,0
0040108D |. C9 LEAVE
0040108E |. C2 1000 RETN 10
00401091 |> B8 01000000 MOV EAX,1
00401096 |. C9 LEAVE
00401097 \. C2 1000 RETN 10
0040109A $-FF25 08204000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; KERNEL32.ExitProcess
004010A0 $-FF25 0C204000 JMP DWORD PTR DS:[<&KERNEL32.GetModuleHa>; KERNEL32.GetModuleHandleA
004010A6 $-FF25 18204000 JMP DWORD PTR DS:[<&USER32.DialogBoxPara>; USER32.DialogBoxParamA
004010AC $-FF25 1C204000 JMP DWORD PTR DS:[<&USER32.EndDialog>] ; USER32.EndDialog
004010B2 $-FF25 20204000 JMP DWORD PTR DS:[<&USER32.GetDlgItemTex>; USER32.GetDlgItemTextA
004010B8 $-FF25 14204000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA
004010BE $-FF25 00204000 JMP DWORD PTR DS:[<&COMCTL32.#17>] ; COMCTL32.InitCommonControls
004010C4 00 DB 00


1) If I add the USER32.dll.MessageBoxA import with LordPE, it does not appear in the list as shown above ? i.e."004010B8 $-FF25 14204000 JMP

DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA" Can I still make calls to this or do I need to somehow make this jump available? If

so, how do I make this jump available like the others?

2) Is it possible to move the code down and insert the code directly into the step by step execution of the code or do I need to jump to

another location and execute my code before I continue with the origional code?

3) If I want to enter my code after the location 004010C4, I can do this but when I try making my jump to the code, it requires more bytes than

for a short jump? How is this overcome?

4) If I need to jump to another location, as described, and the JMP instruction takes more bytes than available, I would presume that I must

recreate the instructions that have been overwritten to perform the jump? Is there any way around this?

5) Is it possible to move the "0040109A $-FF25 08204000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; KERNEL32.ExitProcess" line and all the

others down so that I can continue coding in the SHORT code area ?


I am just trying to establish a few rules about what can and cannot be done with regards to injecting code. Has anyone written a tutorial,

based on the generics of code injection?


Thanks

Hoof

_Servil_
June 17th, 2002, 19:15
hi hoof,
im sorry for OT question, but, how didya enjoy the (RE)tirement?

nikolatesla20
June 17th, 2002, 20:37
As a self-proclaimed code injection "experienced one" of sorts, I can answer at least a few of your questions.

Answers:

#1. The jump does not show up in the normal jump table because that jump table is already coded in the binary executable. When you use LordPE to add an import, it simply tells you how to code the jump. In other words, what address you need to jump to to make the API call. This is actually the address of the first thunk of the API import from the import table, which LordPE modifies. As a side note, if you use Code Snippet Creator for code injection, it actually will make this jump call for you, it inserts it right after your own code that you write in the CSC editor. Otherwise it is up to you to code the "jump" yourself.

#2. It's usually best to redirect the execution to another area, where your own code resides, and then come back to the original code from there. This gives you plenty of room to put your own code, even in a new section if you want.

#3. This is always the problem with trying to "jump" to your code. It is very rare your code will be within range. You need to rethink it Instead of jumping the best way to do it is with a PUSH <address of my code> and then a RET. This will get you anywhere you want to be, and it works just like a jump. I think it is about 10 instructions or so. 68 <address - 8bytes > C3.
You can use the same technique to come back to the original code.

#4. Remember, you do not want to JMP. In my opinion, you are ALWAYS better off with a PUSH, RET. It is more flexible, and it is very rare that your new code will be within range of a short jump anyway. If the PUSH RET combo takes too many bytes, then you simply need to find a better more logical place to insert it into the "chain" of instructions, for example, do not put it in the jump table! However, if you feel you must, and you want to edit the jump table, you could always change the jmp [dword ptr] to go to your own "API" which then does something, and then goes to the real API call afterward. Don't forget to return to the original code as well tho !

#5. Whatever you do, DO NOT move those lines. They are referenced from the actual code. The import table exists in memory, and the jump table jumps to it. The code CALLS the JUMP TABLE, not the imports directly. If you move anything in the jump table you are screwed.

As far as tuts, I can't think of any right now off the top of my head.

-nt20

Hoof Arted
June 17th, 2002, 22:10
This is the stuff I like to read. Good honest answers to some quite stupid questions.

Anyway.... Thanks for the input I will be looking into the things you have said... and hopefully, I or someone else could write a GENERAL tutorial on what you can and cannot do with Code Injection.

As far as retirement goes, you all know what it is like.....


I just cannot stay away..... One day when I have no money and all hell breaks loose, I will need to give up RCE cause they will repo my PC & Laptop


Hoof

JMI
June 17th, 2002, 22:41
Hoof:

Took a quick glance at Kobar's site and he has three tuts on code injection, although two describe themselves as "code insertion." They are by Harlequin, MaV3Rick, and BlackB, so they have the potential of very useful information for your quest. I seem to recall that the Harlequin tut is on the Fravia site, but didn't check.

Google mught be a good choice also. A quick entry of "code injection" got a reference to Lord Rhesus' "Pages of Code Injection", along with 330,999 other entries to check through for ones of interest.

Regards.

CoDe_InSiDe
June 18th, 2002, 06:15
Hi Hoof Arted,

I just want to add this little page, maybe it comes in handy

codeinjection.cjb.etc...

Cya...

CoDe_InSiDe

*edited* i think i shouldn't post early anymore, because i see now that JMI already spoken about this page
argh.... ah well...

JMI
June 18th, 2002, 06:35
Don't be discouraged CoDe_InSiDe. There are still 330,999 more files that I didn't mention by name. Besides, you were trying to help, and that's what counts.


Regards.