Log in

View Full Version : How to add a block of code to a file?


Tom_Smith
July 3rd, 2006, 04:31
Problem:
I want to add a block of consecutive code lines to a .dll file,
i.e., a patch.
I imagine there are two possible ways to do this:
1. Create a new code segment.
Comment: I don't know how to do this.
2. Overwrite existing code that I intend to bypass anyway, nopping it out first.
Comment: I am getting some weird results when I try to do this.

Protection:
This is a HASP situation.
I have already devised the emulator code (the patch).

Tools:
I am using Ollydbg, which I'm pretty proficient at.
I have a good grasp on Assembly language.
I have the Hex editor HexEdit, as well as several others, I don't know if they will come into play here.

Here are the details.

I have a program protected by a HASP.
The HASP protection code is located in a .dll file, let's call it NAMEDELETED.dll.
The basic idea is in NAMEDELETED.dll,
a procedure does all the HASP checking business.
I don't want this procedure executed.
Instead, I want the CALL line to the HASP procedure
to instead call my patch,
namely, a block of code I've written that will emulate the HASP.

It would be easy to do this if I could just create a block of code, append it to NAMEDELETED.dll, and redirect the HASP CALL to the address of the
first line of my patch.
But I don't know how to append a new block of code to a file.

I figured I could nop out each line of the the HASP procedure
(thus the address of the first line of the patch is the same as the nopped HASP procedure).
The patch has far fewer code lines than the HASP procedure, and I would imagine, occupies much less space (bytes).
I nopped the entire HASP procedure in Ollydbg Executable view,
then saved and closed NAMEDELETED.dll.

I now reopen NAMEDELETED.dll, and wouldn't you know it
-in Ollydbg Disassembler view, some of the lines I placed nops in follow this pattern:


Code:
0101304D 90 NOP
0101304E 90 NOP
0101304F 90 NOP
01013050 91 XCHG EAX,ECX
01013051 8190 90909090 90>ADC DWORD PTR DS:[EAX+90909090],90819190
0101305B 90 NOP
0101305C 90 NOP
0101305D 90 NOP


However, in Executable view, all the lines of the former HASP procedure are nops.

Very strange-
don't understand it, don't know how that XCHG EAX,EAX business got there
in Disassembler view.

Anyway, in Ollydbg Executable view, I type in my patch code over the nop lines.

Here is the entire patch (my narrative is continued at bottom):

Code:
00002F93 80FF 01 CMP BH,1
00002F96 75 0B JNZ SHORT 00002FA3
00002F98 33C0 XOR EAX,EAX
00002F9A B0 01 MOV AL,1
00002F9C 33DB XOR EBX,EBX
00002F9E 33C9 XOR ECX,ECX
00002FA0 33D2 XOR EDX,EDX
00002FA2 C3 RETN
00002FA3 80FF 02 CMP BH,2
00002FA6 75 68 JNZ SHORT 00003010
00002FA8 66:81F9 C940 CMP CX,40C9
00002FAD 74 04 JE SHORT 00002FB3
00002FAF 33C0 XOR EAX,EAX
00002FB1 ^EB E9 JMP SHORT 00002F9C
00002FB3 66:3D 3501 CMP AX,135
00002FB7 75 11 JNZ SHORT 00002FCA
00002FB9 66:B8 B74E MOV AX,4EB7
00002FBD 66:BB 6CEB MOV BX,0EB6C
00002FC1 66:B9 C8B5 MOV CX,0B5C8
00002FC5 66:BA 849B MOV DX,9B84
00002FC9 C3 RETN
00002FCA 66:3D C514 CMP AX,14C5
00002FCE 75 11 JNZ SHORT 00002FE1
00002FD0 66:B8 0111 MOV AX,1101
00002FD4 66:BB FD4A MOV BX,4AFD
00002FD8 66:B9 6F76 MOV CX,766F
00002FDC 66:BA 3C21 MOV DX,213C
00002FE0 C3 RETN
00002FE1 66:3D 750F CMP AX,0F75
00002FE5 75 11 JNZ SHORT 00002FF8
00002FE7 66:B8 5D1A MOV AX,1A5D
00002FEB 66:BB 574F MOV BX,4F57
00002FEF 66:B9 8CE3 MOV CX,0E38C
00002FF3 66:BA 785D MOV DX,5D78
00002FF7 C3 RETN
00002FF8 66:83F8 53 CMP AX,53
00002FFC 75 11 JNZ SHORT 0000300F
00002FFE 66:B8 FFA2 MOV AX,0A2FF
00003002 66:BB 97C9 MOV BX,0C997
00003006 66:B9 90AD MOV CX,0AD90
0000300A 66:BA 1F07 MOV DX,71F
0000300E C3 RETN
0000300F CC INT3
00003010 80FF 32 CMP BH,32
00003013 75 0C JNZ SHORT 00003021
00003015 66:8BD0 MOV DX,AX
00003018 33C0 XOR EAX,EAX
0000301A 33C9 XOR ECX,ECX
0000301C 66:BB 0200 MOV BX,2
00003020 C3 RETN
00003021 80FF 47 CMP BH,47
00003024 75 09 JNZ SHORT 0000302F
00003026 33C0 XOR EAX,EAX
00003028 33DB XOR EBX,EBX
0000302A 33C9 XOR ECX,ECX
0000302C 33D2 XOR EDX,EDX
0000302E C3 RETN
0000302F 80FF 49 CMP BH,49
00003032 75 0F JNZ SHORT 00003043
00003034 33C0 XOR EAX,EAX
00003036 33DB XOR EBX,EBX
00003038 33C9 XOR ECX,ECX
0000303A 33D2 XOR EDX,EDX
0000303C B0 08 MOV AL,8
0000303E B3 04 MOV BL,4
00003040 B2 06 MOV DL,6
00003042 C3 RETN
00003043 C3 RETN


So, I save and close NAMEDELETED.dllwith my patch written in,
then reopen NAMEDELETED.dll.

So what are the results?

In Ollydbg Executable view, the patch appears just as I typed it.

But in Ollydbg Disassembler view, I get this (continued below):

Code:
01012F93 80FF 01 CMP BH,1
01012F96 75 0B JNZ SHORT ProductS.01012FA3
01012F98 34 B1 XOR AL,0B1
01012F9A B0 01 MOV AL,1
01012F9C 33DB XOR EBX,EBX
01012F9E 33C9 XOR ECX,ECX
01012FA0 33D2 XOR EDX,EDX
01012FA2 C3 RETN
01012FA3 8000 F4 ADD BYTE PTR DS:[EAX],0F4
01012FA6 75 68 JNZ SHORT ProductS.01013010
01012FA8 66:81F9 C941 CMP CX,41C9
01012FAD 65:04 33 ADD AL,33 ; Superfluous prefix
01012FB0 C0EB E9 SHR BL,0E9 ; Shift constant out of range 1..31
01012FB3 66:3D 36F2 CMP AX,0F236
01012FB7 75 11 JNZ SHORT ProductS.01012FCA
01012FB9 66:B8 B74E MOV AX,4EB7
01012FBD 66:BB 6CEB MOV BX,0EB6C
01012FC1 66:B9 C8B6 MOV CX,0B6C8
01012FC5 57 PUSH EDI
01012FC6 BA 849BC366 MOV EDX,66C39B84
01012FCB 3D C5147511 CMP EAX,117514C5
01012FD0 67:A9 011166BB TEST EAX,BB661101 ; Superfluous prefix
01012FD6 FD STD
01012FD7 4A DEC EDX
01012FD8 66:B9 6F76 MOV CX,766F
01012FDC 66:BB 2D21 MOV BX,212D
01012FE0 C3 RETN
01012FE1 66:3D 750F CMP AX,0F75
01012FE5 76 02 JBE SHORT ProductS.01012FE9
01012FE7 66:B8 5D1A MOV AX,1A5D
01012FEB 66:BB 5840 MOV BX,4058
01012FEF 66:B9 8CE3 MOV CX,0E38C
01012FF3 66:BA 785D MOV DX,5D78
01012FF7 C3 RETN
01012FF8 66:83F9 44 CMP CX,44
01012FFC 75 11 JNZ SHORT ProductS.0101300F
01012FFE 66:B8 FFA2 MOV AX,0A2FF
01013002 67:AC LODS BYTE PTR DS:[SI]
01013004 97 XCHG EAX,EDI
01013005 C9 LEAVE
01013006 66:B9 90AD MOV CX,0AD90
0101300A 66:BB 1007 MOV BX,710
0101300E C3 RETN
0101300F CC INT3
01013010 80FF 32 CMP BH,32
01013013 75 0C JNZ SHORT ProductS.01013021
01013015 66:8BD0 MOV DX,AX
01013018 33C0 XOR EAX,EAX
0101301A 33C9 XOR ECX,ECX
0101301C 66:BB 0200 MOV BX,2
01013020 C3 RETN
01013021 80FF 47 CMP BH,47
01013024 75 0A JNZ SHORT ProductS.01013030
01013026 24 C0 AND AL,0C0
01013028 33DB XOR EBX,EBX
0101302A 33C9 XOR ECX,ECX
0101302C 34 C3 XOR AL,0C3
0101302E C3 RETN
0101302F 80FF 49 CMP BH,49
01013032 75 0F JNZ SHORT ProductS.01013043
01013034 33C0 XOR EAX,EAX
01013036 33DB XOR EBX,EBX
01013038 33C9 XOR ECX,ECX
0101303A 33D2 XOR EDX,EDX
0101303C B0 08 MOV AL,8
0101303E B3 05 MOV BL,5
01013040 A3 06C3C390 MOV DWORD PTR DS:[90C3C306],EAX


The patch code is considerably different in Ollydbg Disassembler view from that in Executable view,
something is changing it, and of course, my patch code is never executed properly, and the program hoses.

So, my question is, how to I properly patch in a block of consecutive code lines?

-Thanks,
Tom.

VeeDub
July 3rd, 2006, 07:48
Hi Tom,

A couple of questions:

Q1.
When you save your file after you have made your changes, are you saving using the same name as the original file - or renaming (i.e. like a Save As).

I have observed some strange behaviour when I tried to save changes to a file - using the same filename. The way to get around this problem is quite simple, save the file with a different name in Olly and then rename the file outside of Olly.

Q2.
When you are savings your changes in the file do you use the 'Copy to executable' -> 'Selection' or 'All modifications'. While if you highlight the selection you would expect both options to have the same result - I have found 'All modifications' to be reliable.

VW

JMI
July 3rd, 2006, 11:59
SECOND RULES VIOLATION OUT OF YOUR FIRST TWO POSTS!!!

Again you make it obvious YOU DID NOT READ THE FRIGGIN FAQ or you would know that you are NOT to post information identifying the target AND then post TARGET SPECIFIC CODE. You can clearly see NOW, that you left "a target identifying name" in 6 places in your posted code.

You are now on a very short leash and further failure to follow the posting rules will send you to oblivion.

Regards,

Tom_Smith
July 3rd, 2006, 21:44
The name of the .dll I posted is fake.

I thought that was kind of obvious.

There was no need to excise it.

-Tom.

Tom_Smith
July 3rd, 2006, 21:59
VeeDub:

Thanks for the response regarding my post
-"How to add a block of code to a file?"

Answers to your questions:

I am saving the file using the same name as the original file
-I will try saving it under a different name, then changing it back to the original name outside of Ollydbg and seeing how that works.

As for my method, when
I did the work in the Disassembler window, and
did a "Copy to executable"/"Selection" or "All Modifications",
either way, the results were the same
-I got this message from Ollybg
_______________________
Please confirm updating of fixups:
Selection contains modified fixups.
When loading this DLL, OS will adjust fixups, thus modifying your code.
Were you not careful enough, this may have disasterous effects on the debugged program.
Do you still want to update executable file?
__________________________

And when I hit the "Yes" button and copied everything to the
executable, I got the results in my post.

So I then redid the whole thing using the original file, this time
directly in executable view, and though I did not get that
"Please confirm updating of fixups" message, the results were the same as doing the work in the Disassembler window
- the code looked as it did in my post.

-Tom.

Tom_Smith
July 3rd, 2006, 22:24
Actually, I had saved the file under a different name.

I tried it again:

I used the original file, did my nops, and saved it under a new name.

I then changed the file under the new name to the original name,
and replaced the original file with it.

The results are the same as in my initial post.

-Tom.

Knight
July 4th, 2006, 00:29
I think that all problems are because of relocations. You should remove all relocation table entries that fall in your noped area (this can be hard since as far as i know there ain't PE Editor which would allow edit relocations) or abandon it and look for place somewhere else.

Regards,
Knight

Tom_Smith
July 4th, 2006, 06:33
First, I want to thank everyone who posted a response to my post
-I appreciate your help.

Here is what I discovered:
At certain points in my .dll, and I guess in .dlls in general, there are blocks of consecutive lines reading:
ADD BYTE PTR DS:[EAX],AL

These blocks are known as "Code Caves"
- areas of "0"s where you can insert code.

Provided the total size of your inserted code block is less than the available code caves
-you have your empty space.

There can be other complications- such as if your patch calls relative addresses
-I am still unschooled on this, I guess I'll have to slowly educate myself on
these complications.

But, in my case, I am just manipulating the EAX, EBX, ECX, and EDX registers
-so the code cave method works.

-Tom.

XweAponX
July 4th, 2006, 19:36
Very Interesting post Tom, and very interesting responses. I lurk here often. The question posed and the valid reponses given help me with a similar problem.

Again, I want to thank everyone who answered this post with VALID responses.

"Regards"

Nacho_dj
July 5th, 2006, 05:14
As a matter of fact, I have coded a tool that needs to insert code in a cave to redirect some calls, but the code is only MOV AL,1 RETN, so 3 bytes needed.

I only subtract 0x10 to the RawOffset+RawSize of code section and then I patch there. Till now I have found always that area full of zeroes, as compilers round raw sizes to 0x1000, so you could assure it will very easy always finding areas full of zeroes at the end of any code section.

Cheers

Nacho_dj

JMI
July 5th, 2006, 10:10
It must be just a happy "coincidence" that the mystery "lurker" XweAponX, appeared suddenly, out of the mist, to "VALIDATE" some of the responses to Tom_Smith's Thread when, gasp, both of them just "happen" to share the very same IP block issued from Cox Atlanta Communications.

But then, some people are "clever by half" when they attempt to deceive.

But it was a nice try.



Regards,

Kayaker
July 5th, 2006, 11:53
Quote:
gasp, both of them just "happen" to share the very same IP block
But then, some people are "clever by half" when they attempt to deceive.


Heheh. You mean to say JMI that this is not merely a coincidence, a random event? I think then this could only be explained by Carl Jung's concept of 'synchronicity' or 'acausal connecting principle'.

Such a 'meaningful coincidence' as proposed by Jung (as opposed to this being an event governed by causality), may involve the psyche somehow operating on external reality to 'cause' such a coincidence. Indeed, such a proposition must question our known laws of space and time and what we believe to be true may have no real objective existence.

Oh dear, this is becoming too existential, time to consult the I-Ching...


JMI
July 5th, 2006, 12:50
Especially that part about "the evolution of events as a process."

But Tom_Smith/XweAponX is/are too "Jung" to have read such works.

Pardon the bad pun. I couldn't resist. Absolutely no impuls control. (heck, I couldn't even spell it correctly, the first time)

Regards,