9.1.5 Task 1.5 Hint #1: Keep in mind that __v — global variable. Hint #2: That function is called in startup code, be<strong>for</strong>e main() execution. Solution: early Pentium CPU FDIV bug checking 1 . C source code: unsigned _v; // _v enum e { PROB_P5_DIV = 0x0001 }; void f( void ) // __verify_pentium_fdiv_bug { /* Verify we have got the Pentium FDIV problem. The volatiles are <strong>to</strong> scare the optimizer away. */ volatile double v1 = 4195835; volatile double v2 = 3145727; } if( (v1 - (v1/v2)*v2) > 1.0e-8 ) { _v |= PROB_P5_DIV; } 9.1.6 Task 1.6 Hint: it might be helpful <strong>to</strong> google a constant used here. Solution: TEA encryption algorithm 2 . C source code (taken from http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm): void f (unsigned int* v, unsigned int* k) { unsigned int v0=v[0], v1=v[1], sum=0, i; /* set up */ unsigned int delta=0x9e3779b9; /* a key schedule constant */ unsigned int k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */ <strong>for</strong> (i=0; i < 32; i++) { /* basic cycle start */ sum += delta; v0 += ((v15) + k1); v1 += ((v05) + k3); } /* end cycle */ v[0]=v0; v[1]=v1; } 9.1.7 Task 1.7 Hint: the table contain pre-calculated values. It’s possible <strong>to</strong> implement the function without it, but it will work slower, though. Solution: this function <strong>reverse</strong> all bits in input 32-bit integer. It’s lib/bitrev.c from Linux kernel. C source code: 1 http://en.wikipedia.org/wiki/Pentium_FDIV_bug 2 Tiny Encryption Algorithm 201
const unsigned char byte_rev_table[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; unsigned char bitrev8(unsigned char byte) { return byte_rev_table[byte]; } unsigned short bitrev16(unsigned short x) { return (bitrev8(x & 0xff) > 8); } /** * bitrev32 - <strong>reverse</strong> the order of bits in a unsigned int value * @x: value <strong>to</strong> be bit-<strong>reverse</strong>d */ unsigned int bitrev32(unsigned int x) { return (bitrev16(x & 0xffff) > 16); 202
- Page 1 and 2:
Quick introduction to reverse engin
- Page 3 and 4:
1.16 C++ classes . . . . . . . . .
- Page 5 and 6:
Preface Here (will be) some of my n
- Page 7 and 8:
1.1 Hello, world! Let’s start wit
- Page 9 and 10:
1.2 Stack Stack — is one of the m
- Page 11 and 12:
(_snprintf() function works just li
- Page 13 and 14:
1.3 printf() with several arguments
- Page 15 and 16:
1.4 scanf() Now let’s use scanf()
- Page 17 and 18:
GCC replaced first printf() call to
- Page 19 and 20:
}; return 0; printf ("What you ente
- Page 21 and 22:
1.5 Passing arguments via stack Now
- Page 23 and 24:
1.6 One more word about results ret
- Page 25 and 26:
push OFFSET $SG741 ; ’a
- Page 27 and 28:
1.8 switch()/case/default 1.8.1 Few
- Page 29 and 30:
1.8.2 A lot of cases If switch() st
- Page 31 and 32:
loc_804840C: ; DATA XREF: .rodata:0
- Page 33 and 34:
et 0 _main ENDP Nothing very specia
- Page 35 and 36:
add esp, 1Ch xor eax, eax ; return
- Page 37 and 38:
C/C++ standard defines char type as
- Page 39 and 40:
eax=eax+ecx return eax ... and this
- Page 41 and 42:
mov eax, ecx imul edx sar edx, 1 mo
- Page 43 and 44:
; current stack state: ST(0) = resu
- Page 45 and 46:
; in local stack here 8 bytes still
- Page 47 and 48:
fld QWORD PTR _a$[esp-4] ; current
- Page 49 and 50:
In other words, fnstsw ax / sahf in
- Page 51 and 52:
1.13 Arrays Array is just a set of
- Page 53 and 54:
mov [esp+70h+var_70], eax call _pri
- Page 55 and 56:
jge SHORT $LN1@main mov ecx, DWORD
- Page 57 and 58:
ebp 0x15 0x15 esi 0x0 0 edi 0x0 0 e
- Page 59 and 60:
1.14 Bit fields A lot of functions
- Page 61 and 62:
So, let’s download Linux Kernel 2
- Page 63:
There are some redundant code prese
- Page 66 and 67:
y 10 just by dropping last digit (3
- Page 68 and 69:
_key$ = 8 ; size = 4 _len$ = 12 ; s
- Page 70 and 71:
1.15 Structures It can be defined t
- Page 72 and 73:
call DWORD PTR __imp__GetSystemTime
- Page 74 and 75:
1.15.4 Fields packing in structure
- Page 76 and 77:
}; int b; struct outer_struct { cha
- Page 78 and 79:
}; printf ("stepping=%d\n", tmp->st
- Page 80 and 81:
call ___printf_chk mov eax, esi shr
- Page 82 and 83:
mov edx, DWORD PTR _t$[ebp] or edx,
- Page 84 and 85:
1.16 C++ classes I placed a C++ cla
- Page 86 and 87:
push ecx mov DWORD PTR _this$[ebp],
- Page 88 and 89:
call _ZN1c4dumpEv lea eax, [esp+20h
- Page 90 and 91:
1.17 Unions 1.17.1 Pseudo-random nu
- Page 92 and 93:
xor eax, eax pop esi mov esp, ebp p
- Page 94 and 95:
Let’s compile it in MSVC 2010 (I
- Page 96 and 97:
comp() function: public comp comp p
- Page 98 and 99:
Some compilers can do vectorization
- Page 100 and 101:
mov ecx, [esp+10h+var_10] mov edx,
- Page 102 and 103:
GCC In all other cases, non-SSE2 co
- Page 104 and 105:
add ebx, edx lea esi, [esi+0] loc_8
- Page 106 and 107:
movdqa xmm1, XMMWORD PTR [ecx+16] a
- Page 108 and 109:
1.20 x86-64 It’s a 64-bit extensi
- Page 110 and 111:
} x40 = a3 | x31; x41 = x24 & ~x37;
- Page 112 and 113:
or ebx, DWORD PTR _x6$[esp+36] mov
- Page 114 and 115:
and r11, r8 and rsi, r8 and r10, r1
- Page 116 and 117:
pop rdi pop rsi ret 0 s1 ENDP Nothi
- Page 118 and 119:
2.1 LEA instruction LEA (Load Effec
- Page 120 and 121:
2.3 npad It’s an assembler macro
- Page 122 and 123:
2.4 Signed number representations T
- Page 124 and 125:
call function function: .. do somet
- Page 126 and 127:
3.2 String Debugging messages are o
- Page 128 and 129:
.text:3011E91B DD 1E fstp qword ptr
- Page 130 and 131:
loc_80483F2: pop ebp retn _f endp 4
- Page 132 and 133:
loc_8048444: loc_8048448: loc_80484
- Page 134 and 135:
public f2 f2 proc near push ebp mov
- Page 136 and 137:
loc_804840A: loc_804842E: loc_80484
- Page 138 and 139:
mov esi, DWORD PTR _k$[esp+16] push
- Page 140 and 141:
or eax, edx retn f endp 4.1.8 Task
- Page 142 and 143:
4.2 Middle level 4.2.1 Task 2.1 Wel
- Page 144 and 145:
mov [edx+eax], bl mov ebx, edi mov
- Page 146 and 147:
loc_80485AB: ; CODE XREF: f+1E0 ; f
- Page 148 and 149:
mov [ecx+eax], dl inc eax cmp ebx,
- Page 150 and 151:
Chapter 5 Tools ∙ IDA as disassem
- Page 152 and 153:
Chapter 7 More examples 147
- Page 154 and 155:
.text:00541050 arg_0 = dword ptr 4
- Page 156 and 157: .text:005410F3 .text:005410F3 loc_5
- Page 158 and 159: .text:005411A9 pop ebx .text:005411
- Page 160 and 161: .text:00541249 .text:00541249 next_
- Page 162 and 163: .text:005412FC mov esi, offset cube
- Page 164 and 165: .text:005413DC call _fwrite ; write
- Page 166 and 167: .text:005414A7 push ecx ; Filename
- Page 168 and 169: .text:005413A3 mov ecx, [esp+44h+pa
- Page 170 and 171: .text:00541408 push offset aRb ; "r
- Page 172 and 173: }; }; return; fseek (f, 0, SEEK_END
- Page 174 and 175: .text:005411B5 mov ebp, eax Check f
- Page 176 and 177: .text:0054124C inc ebp .text:005412
- Page 178 and 179: This instruction clears bit, in oth
- Page 180 and 181: .text:005410CD add esp, 40h .text:0
- Page 182 and 183: }; for (i=0; i
- Page 184 and 185: }; tmp[y][z]=get_bit (row, y, z); f
- Page 186 and 187: }; fread (buf, flen, 1, f); fclose
- Page 188 and 189: 7.2 SAP client network traffic comp
- Page 190 and 191: .text:64413F68 .text:64413F68 loc_6
- Page 192 and 193: .text:64405171 call dbg .text:64405
- Page 194 and 195: .text:64404FF7 push offset aLogging
- Page 196 and 197: .text:64405113 loc_64405113: .text:
- Page 198 and 199: Now let’s dig deeper and find con
- Page 200 and 201: .text:64411E0B .text:64411E0B loc_6
- Page 202 and 203: Chapter 8 Other things 8.1 Compiler
- Page 204 and 205: Chapter 9 Tasks solutions 9.1 Easy
- Page 208 and 209: } 9.1.8 Task 1.8 Solution: two 100*
- Page 210 and 211: #define PUSH(low, high) ((void) ((t
- Page 212 and 213: } } ignore one or both. Otherwise,