experiment : convert function as shellCode on our C project
发布日期:2021-06-30 22:01:52 浏览次数:2 分类:技术文章

本文共 3348 字,大约阅读时间需要 11 分钟。

ShellCode对应的函数,  一般都是动态调试时发现的. 又不想逆向成C, 才使用的ShellCode.

暂时不知道在ShellCode中,如何使用带重定位信息的变量. e.g. 一个字符串.

// ShellCode-1.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
/// 如果是函数较长, 用手工整理成ShellCode数组有点不现实/// 在OD中将对应的2进制代码复制, 右键菜单 => 备份 => 保存数据到文件/// mem保存后, 是4096对齐的, 将*.mem中函数末尾之后的文本删除/// 用UtrlEdit等编辑工具将 *.mem 修正成只包含函数实现的二进制文件/// 16进制编辑该文件后,选中不需要的二进制数据,选择16进制删除, 数量填N大/// 用 bin2c *_fix.mem 转成数组文件, bin2c是开源工程/// 将bin2c.exe 和 *.mem 放在一起, 写个.cmd来转换/// bin2c.bat 内容/**@echo offtitle Bin2ccolor 0Becho.echo 二进制文件(*.mem)转成数组echo.: ShellCod_00401000-fix.memBin2c.exe ShellCod_00401000-fix.mem ShellCodeArray.h byShellCodeecho.echo 转换完成...echo.pause*/unsigned char byShellCode[] = { 0x55, 0x8b, 0xec, 0x51, 0x8b, 0x45, 0x08, 0x03, 0x45, 0x0c, 0x89, 0x45, 0xfc, 0x8b, 0x45, 0xfc, 0x8b, 0xe5, 0x5d, 0xc3};/// fnAdd 的函数调用方式声明 要与原函数对应, 看是 _stdcall ,还是 _cdecl/**工程选项 : Configuration Properties => C/C++ => Advanced => Calling Convention 可以看到默认的函数调用方式, 如果函数定义时没制定, 以这里为准. vs2010 Release x86 默认的函数调用方式为 _cdecl*//// 一般情况,这段ShellCode 都是从第三方PE, 逆向出来的, 具体的函数调用方式, 可以用OD动态调试来观察typedef DWORD(_cdecl * pfn_fnAdd)(int iParamL, int iParamR);/// fnAdd 的反汇编, 从OD复制出来的/**00401000 /$ 55 push ebp00401001 |. 8BEC mov ebp, esp00401003 |. 51 push ecx00401004 |. 8B45 08 mov eax, dword ptr [ebp+8]00401007 |. 0345 0C add eax, dword ptr [ebp+C]0040100A |. 8945 FC mov dword ptr [ebp-4], eax0040100D |. 8B45 FC mov eax, dword ptr [ebp-4]00401010 |. 8BE5 mov esp, ebp00401012 |. 5D pop ebp00401013 \. C3 retn*//**DWORD fnAdd(int iParamL, int iParamR){ DWORD dwRc = iParamL + iParamR; /// 需要转成ShellCode的函数, 里面不能包含重定位的代码 /// e.g. 常量串的偏移 /// 最好是纯逻辑的代码 return dwRc;}*/int _tmain(int argc, _TCHAR* argv[]){ BOOL bRc = FALSE; DWORD dwRc = 0; int iParamL = 0; int iParamR = 0; DWORD dwLenFunction = 0; ///< 函数size DWORD dwOldProtect = 0; BYTE * pbCall = byShellCode; pfn_fnAdd fnAdd = NULL; /// 设置ShellCode所在数组为可读写可执行 bRc = VirtualProtect( pbCall, sizeof(byShellCode), PAGE_EXECUTE_READWRITE, &dwOldProtect); if (!bRc) { _tprintf(L"error : VirtualProtect set \r\n"); goto _tmain_END; } _tprintf(L"when set, dwOldProtect = 0x%X\r\n", dwOldProtect); fnAdd = (pfn_fnAdd)pbCall; iParamL = rand(); iParamR = rand(); dwRc = fnAdd(iParamL, iParamR); _tprintf(L"fnAdd(0x%X, 0x%X) = 0x%X\r\n", iParamL, iParamR, dwRc); /// 恢复ShellCode数组原来的页保护方式 bRc = VirtualProtect( pbCall, sizeof(byShellCode), dwOldProtect, &dwOldProtect); if (!bRc) { _tprintf(L"error : VirtualProtect restore \r\n"); goto _tmain_END; } _tprintf(L"when restore, dwOldProtect = 0x%X\r\n", dwOldProtect);_tmain_END: _tprintf(L"END, press any key to quit\r\n"); getwchar(); /** run results when set, dwOldProtect = 0x4 fnAdd(0x29, 0x4823) = 0x484C when restore, dwOldProtect = 0x40 END, press any key to quit */ return 0;}

转载地址:https://lostspeed.blog.csdn.net/article/details/10352409 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:cJSON指定内存分配函数
下一篇:MDK5 #254: type name is not allowed

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月17日 10时11分23秒