| 001 | void obfuscateOpcode( UCHAR* opcodeAddress, unsigned long opcodeLength ) |
| 002 | { |
| 003 | MEMORY_BASIC_INFORMATION mbi; |
| 004 | |
| 005 | VirtualQuery( opcodeAddress, &mbi, sizeof( mbi ) ); |
| 006 | |
| 007 | VirtualProtect( mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect ); |
| 008 | |
| 009 | if( opcodeLength == 1 ) |
| 010 | { |
| 011 | if( opcodeAddress[0] == 0xC3 && opcodeAddress[1] == 0xCC && opcodeAddress[2] == 0xCC ) |
| 012 | { |
| 013 | // retn -> retn (0) |
| 014 | |
| 015 | opcodeAddress[0] = 0xC2; |
| 016 | opcodeAddress[1] = 0x00; |
| 017 | opcodeAddress[2] = 0x00; |
| 018 | |
| 019 | if(printOutput) printf( "retn -> retn (0) [0x%X]\n", opcodeAddress ); |
| 020 | } |
| 021 | else if( opcodeAddress[0] == 0xCC && opcodeLength == 1 ) |
| 022 | { |
| 023 | srand( GetCurrentProcessId() * GetTickCount() ); |
| 024 | |
| 025 | opcodeAddress[0] = rand() % 0xFF; |
| 026 | |
| 027 | if(printOutput) printf( "CC -> rand [0x%X]\n", opcodeAddress ); |
| 028 | } |
| 029 | } |
| 030 | else if( opcodeLength == 2 ) |
| 031 | { |
| 032 | if( opcodeAddress[0] == 0xD8 && ( opcodeAddress[1] >= 0xD8 && opcodeAddress[1] <= 0xDF ) ) |
| 033 | { |
| 034 | unsigned char asm_reg = opcodeAddress[1] - 0xD8; |
| 035 | |
| 036 | // fcomp st might be broken for 0, again. |
| 037 | |
| 038 | if( rand() % 2 ) |
| 039 | { |
| 040 | opcodeAddress[0] = 0xDE; // fcomp st -> fcomp3 st (Identical in IDA) |
| 041 | opcodeAddress[1] = 0xD0 + asm_reg; |
| 042 | |
| 043 | if(printOutput) printf( "fcomp st -> fcomp3 st [0x%X]\n", opcodeAddress ); |
| 044 | } |
| 045 | else |
| 046 | { |
| 047 | opcodeAddress[0] = 0xDC; // fcomp st -> fcomp5 st |
| 048 | |
| 049 | if(printOutput) printf( "fcomp st -> fcomp5 st [0x%X]\n", opcodeAddress ); |
| 050 | } |
| 051 | } |
| 052 | else if( opcodeAddress[0] == 0xD8 && ( opcodeAddress[1] >= 0xD0 && opcodeAddress[1] <= 0xD7 ) ) |
| 053 | { |
| 054 | opcodeAddress[0] = 0xDC; // fcom st -> fcom2 st (Identical in IDA) |
| 055 | |
| 056 | if(printOutput) printf( "fcom st -> fcom2 st [0x%X]\n", opcodeAddress ); |
| 057 | } |
| 058 | else if( opcodeAddress[0] == 0xDD && ( opcodeAddress[1] >= 0xD8 && opcodeAddress[1] <= 0xDF ) ) |
| 059 | { |
| 060 | unsigned char asm_reg = opcodeAddress[1] - 0xD8; |
| 061 | |
| 062 | // fstp st (0) might be broken, I'm not even entirely sure |
| 063 | |
| 064 | switch( rand() % 3 ) |
| 065 | { |
| 066 | case 0: |
| 067 | opcodeAddress[0] = 0xD9; // fstp st -> fstp1 st |
| 068 | if(printOutput) printf( "fstp st -> fstp1 st st [0x%X]\n", opcodeAddress ); |
| 069 | break; |
| 070 | case 1: |
| 071 | opcodeAddress[0] = 0xDF; // fstp st -> fstp8 st |
| 072 | opcodeAddress[1] = 0xD0 + asm_reg; |
| 073 | if(printOutput) printf( "fstp st -> fstp8 st [0x%X]\n", opcodeAddress ); |
| 074 | break; |
| 075 | case 2: |
| 076 | opcodeAddress[0] = 0xDF; // fstp st -> fstp9 st |
| 077 | if(printOutput) printf( "fstp st -> fstp9 st [0x%X]\n", opcodeAddress ); |
| 078 | break; |
| 079 | } |
| 080 | } |
| 081 | else if( opcodeAddress[0] == 0xD9 && ( opcodeAddress[1] >= 0xC8 && opcodeAddress[1] <= 0xCF ) ) |
| 082 | { |
| 083 | // FXCH ST(i) |
| 084 | |
| 085 | opcodeAddress[0] = 0xDF; // FXCH ST(i) -> FXCH7 ST(i) |
| 086 | |
| 087 | if(printOutput) printf( "FXCH ST(i) -> FXCH7 ST(i) [0x%X]\n", opcodeAddress ); |
| 088 | } |
| 089 | } |
| 090 | else if( opcodeLength == 3 ) |
| 091 | { |
| 092 | // add reg, num -> inc (num), recursive, nop |
| 093 | |
| 094 | if( opcodeAddress[0] == 0x83 && ( opcodeAddress[1] >= 0xC0 && opcodeAddress[1] <= 0xC7 ) && opcodeAddress[2] <= 3 ) |
| 095 | { |
| 096 | unsigned char asm_reg = opcodeAddress[1] - 0xC0; |
| 097 | unsigned char asm_add = opcodeAddress[2]; |
| 098 | |
| 099 | for( unsigned char i = 0; i < 3; i++ ) |
| 100 | { |
| 101 | if( i >= asm_add ) |
| 102 | { |
| 103 | opcodeAddress[i] = 0x90; |
| 104 | |
| 105 | continue; |
| 106 | } |
| 107 | |
| 108 | opcodeAddress[i] = 0x40 + asm_reg; |
| 109 | } |
| 110 | |
| 111 | if(printOutput) printf( "add reg, num -> inc (num), recursive, nop [0x%X]\n", opcodeAddress ); |
| 112 | } |
| 113 | |
| 114 | // sub reg, num -> dec (num), recursive, nop |
| 115 | |
| 116 | else if( opcodeAddress[0] == 0x83 && ( opcodeAddress[1] >= 0xE8 && opcodeAddress[1] <= 0xEF ) && opcodeAddress[2] <= 3 ) |
| 117 | { |
| 118 | unsigned char asm_reg = opcodeAddress[1] - 0xE8; |
| 119 | unsigned char asm_sub = opcodeAddress[2]; |
| 120 | |
| 121 | for( unsigned char i = 0; i < 3; i++ ) |
| 122 | { |
| 123 | if( i >= asm_sub ) |
| 124 | { |
| 125 | opcodeAddress[i] = 0x90; |
| 126 | |
| 127 | continue; |
| 128 | } |
| 129 | |
| 130 | opcodeAddress[i] = 0x48 + asm_reg; |
| 131 | } |
| 132 | |
| 133 | if(printOutput) printf( "sub reg, num -> dec (num), recursive, nop [0x%X]\n", opcodeAddress ); |
| 134 | } |
| 135 | } |
| 136 | else if( opcodeLength == 5 ) |
| 137 | { |
| 138 | // mov reg, num -> xor reg, reg; xor reg, num |
| 139 | |
| 140 | if( opcodeAddress[0] >= 0xB8 && opcodeAddress[0] <= 0xBF ) |
| 141 | { |
| 142 | DWORD lengthToMov = *( DWORD* )( opcodeAddress + 1 ); |
| 143 | |
| 144 | UCHAR asm_reg = opcodeAddress[0] - 0xB8; |
| 145 | |
| 146 | // 0xF or below |
| 147 | if( lengthToMov < 16 ) |
| 148 | { |
| 149 | opcodeAddress[0] = 0x33; |
| 150 | opcodeAddress[1] = 0xC0 + ( asm_reg * 9 ); |
| 151 | opcodeAddress[2] = 0x83; |
| 152 | opcodeAddress[3] = 0xF0 + asm_reg; |
| 153 | opcodeAddress[4] = ( unsigned char ) lengthToMov; |
| 154 | |
| 155 | if(printOutput) printf( "mov reg, num -> xor reg, reg; xor reg, num (0) [0x%X]\n", opcodeAddress ); |
| 156 | } |
| 157 | else if( lengthToMov <= 0xFF && asm_reg == 0 ) |
| 158 | { |
| 159 | // xor eax, eax |
| 160 | opcodeAddress[0] = 0x33; |
| 161 | opcodeAddress[1] = 0xC0 + ( asm_reg * 9 ); |
| 162 | |
| 163 | // add al, num (can probably be used for bl, cl too) |
| 164 | opcodeAddress[2] = 0x04; |
| 165 | opcodeAddress[3] = ( unsigned char ) lengthToMov; |
| 166 | |
| 167 | if(printOutput) printf( "mov eax, num -> xor eax, eax, add al, num [0x%X]\n", opcodeAddress ); |
| 168 | } |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | VirtualProtect( mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL ); |
| 173 | } |