|
-
September 4th, 2002, 12:06 AM
#1
Junior Member
Byte Patches
How do they work, exactly?
I copied an exe, and ran a byte patch on one. Then I compared the patched file to the original file in a hex editor. The programs were the exact same except for one byte. (Actually, 4 bits, half a byte.) Interestingly enough, there was a massive difference in two programs. How can 4bits make such a dramatic difference in a program, though?
The only things I could think of are comments, and operator, or boolean conditions. However, I do not think that comments get compiled, correct me if I'm wrong. If you change an "or" to an "and" or change a "true" to a "false" or vice versa, I see how a large section of code, which may not have been executed (at all or under certain conditions) may now be executed. However...
When I think of boolean, I think binary. On or off. 1 or 0. If I were to have changed a boolean condition, wouldn't I have changed a hex value from 00 to 01, or vice versa? I don't know what the operators hex values are, though. All I know is that when this specific byte is 85, the program behaves how it is supposed to. But, when it is any other value, 84, 86, etc. it changes. But the change is the same with any other byte. Do you know what it could be, I'm just curious.
Thanks,
Ramzi
-
September 4th, 2002, 12:40 AM
#2
If the byte is a data value, the wrong byte may only cause a minor error
(or a major one) in the results of a calculation, giving you the wrong
answer to a math problem, for instance. If it is a text character, maybe only
a word might be misspelled or something, but if the byte is one
of the program's machine instructions, even one bit can make the difference
between running and crashing.
Certain bit combinations (opcodes) constitute the processor's instruction set
and each one is unique, and may do radically different things when executed.
I came in to the world with nothing. I still have most of it.
-
September 4th, 2002, 05:48 AM
#3
Senior Member
How can 4bits make such a dramatic difference in a program, though?
consider the logical structure of an assembled program, where offsets are used for execution flow. in the following simplistic example, such a 4 bit change can be seen.
Code:
0x80483d0 <main>: push %ebp; adds previous fp to stack
0x80483d1 <main+1>: mov %esp,%ebp; copies sp to fp
0x80483d3 <main+3>: sub $0x8,%esp; allocates stack space for local vars
0x80483d6 <main+6>: movl $0x1,0xfffffffc(%ebp); sets local var1=1
0x80483dd <main+13>: movl $0x2,0xfffffff8(%ebp); sets local var2=2
0x80483e4 <main+20>: mov 0xfffffffc(%ebp),%eax; copies var1 to eax
0x80483e7 <main+23>: cmp 0xfffffff8(%ebp),%eax; compares eax to var2: start of test block
0x80483ea <main+26>: jne 0x8048400 <main+48>; jump if not equal: action for test block
0x80483ec <main+28>: push $0x8048470; adds string to stack: start of test=true case
0x80483f1 <main+33>: call 0x8048308 <printf>; calls printf
0x80483f6 <main+38>: add $0x4,%esp; removes string from stack
0x80483f9 <main+41>: jmp 0x804840d <main+61>; jumps to end of test block
0x80483fb <main+43>: nop;
0x80483fc <main+44>: lea 0x0(%esi,1),%esi; ???
0x8048400 <main+48>: push $0x8048477; adds string to stack: start of test=false case
0x8048405 <main+53>: call 0x8048308 <printf>; calls printf
0x804840a <main+58>: add $0x4,%esp; removes string from stack
0x804840d <main+61>: xor %eax,%eax; sets eax to 0
0x804840f <main+63>: jmp 0x8048411 <main+65>; jumps to end of test block
0x8048411 <main+65>: leave; tears down stack frame
0x8048412 <main+66>: ret; set's eax to return and re-establishes eip from stack
0x8048413 <main+67>: nop;
normal execution will cause the test to fail...but a byte or less than byte change to any of the following lines can result in a true test.
variable manipulation
- changing the last octet of the second word at main+13 from 0x2 to 0x1. (2 bits difference)
Code:
;before
0x80483dd <main+13>: movl $0x2,0xfffffff8(%ebp); sets local var2=2
0xc7 0x45 0xf8 0x02
0x00 0x00 0x00
;after
0x80483dd <main+13>: movl $0x1,0xfffffff8(%ebp); sets local var2=1
0xc7 0x45 0xf8 0x01
0x00 0x00 0x00
offset manipulation
changing the last octet in the first word at main+26 from 0x14 to 0x02 (2 bits difference)
Code:
;before
0x80483ea <main+26>: jne 0x8048400 <main+48>; jump if not equal: action for test block
0x75 0x14
;after
0x80483ea <main+26>: jne 0x80484ec <main+28>; jump if not equal: action for test block
0x75 0x02
code manipulation
changing the instruction and offset at main+26 from 0x75 0x14 to 0x90 0x90 (2 bytes difference)
Code:
; before
0x80483ea <main+26>: jne 0x8048400 <main+48>; jump if not equal: action for test block
0x75 0x14
; after
0x80483ea <main+26>: nop;
0x80483eb <main+27>: nop;
0x90 0x90
granted these are all simplistic examples, but hopefully it helps to illustrate the effects of such changes...if simple test's like these are used at program initialization to validate and set global variables that are used through the lifetime of the process, and those variables are used to determine more significant application flow - then even these simple examples can be applied.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|