Byte Patches
Results 1 to 3 of 3

Thread: Byte Patches

  1. #1
    Junior Member
    Join Date
    Aug 2002
    Posts
    19

    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

  2. #2
    AO Curmudgeon rcgreen's Avatar
    Join Date
    Nov 2001
    Posts
    2,716
    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.

  3. #3
    Senior Member
    Join Date
    Jun 2002
    Posts
    165
    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.
    -droby10

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •