逆向工程核心原理读书笔记-代码注入
代码注入是一种向目标进程插入独立运行代码并使之运行的技术,它一般调用CreateRemoteThread()API以远程线程形式运行插入的代码,所以也被称为线程注入。
和DLL注入相比代码注入占用内存少并难以查找痕迹。所以DLL注入技术主要用在代码量大且复杂的时候,而代码注入技术则适用于代码量小且简单的情况比如shellcode。下面我们先测试一下代码。
运行notepad.exe并查看PID。
在命令行窗口中输入命令与参数。
notepad.exe弹出一个消息框,如图所示。
我们来分析一下源代码,看看是怎么实现的。
首先看一下main函数。main函数用来调用InjectCode()函数,传入的函数参数为目标进程的PID。
- int main(int argc, char *argv[])
- {
- DWORD dwPID = 0;
- if( argc != 2 )
- {
- printf("\n USAGE : %s <pid>\n", argv[0]);
- return 1;
- }
- // change privilege
- if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
- return 1;
- // code injection
- dwPID = (DWORD)atol(argv[1]);
- InjectCode(dwPID);
- return 0;
- }
分析InjectCode()函数之前,先看一下要注入的目标进程的代码。函数中并未直接调用相关API,也未直接定义使用字符串,它们都通过THREAD_PARAM结构体以线程参数的形式传递调用。
- typedef struct _THREAD_PARAM
- {
- FARPROC pFunc[2]; // LoadLibraryA(), GetProcAddress()
- char szBuf[4][128]; // "user32.dll", "MessageBoxA", "www.reversecore.com", "ReverseCore"
- } THREAD_PARAM, *PTHREAD_PARAM;
- typedef HMODULE (WINAPI *PFLOADLIBRARYA)
- (
- LPCSTR lpLibFileName
- );
- typedef FARPROC (WINAPI *PFGETPROCADDRESS)
- (
- HMODULE hModule,
- LPCSTR lpProcName
- );
- typedef int (WINAPI *PFMESSAGEBOXA)
- (
- HWND hWnd,
- LPCSTR lpText,
- LPCSTR lpCaption,
- UINT uType
- );
- DWORD WINAPI ThreadProc(LPVOID lParam)
- {
- PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
- HMODULE hMod = NULL;
- FARPROC pFunc = NULL;
- // LoadLibrary()
- hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]); // "user32.dll"
- if( !hMod )
- return 1;
- // GetProcAddress()
- pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]); // "MessageBoxA"
- if( !pFunc )
- return 1;
- // MessageBoxA()
- ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
- return 0;
- }
InjectCode()是代码注入技术的核心部分。两次调用VirtualAllocEx和WriteProcessMemory,第一次调用分配内存空间并写入远程线程的数据,第二次调用分配内存空间并写入远程线程的代码。这是代码注入的一个非常重要的特征。
- BOOL InjectCode(DWORD dwPID)
- {
- HMODULE hMod = NULL;
- THREAD_PARAM param = {0,};
- HANDLE hProcess = NULL;
- HANDLE hThread = NULL;
- LPVOID pRemoteBuf[2] = {0,};
- DWORD dwSize = 0;
- hMod = GetModuleHandleA("kernel32.dll");
- // set THREAD_PARAM
- param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
- param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
- strcpy_s(param.szBuf[0], "user32.dll");
- strcpy_s(param.szBuf[1], "MessageBoxA");
- strcpy_s(param.szBuf[2], "www.reversecore.com");
- strcpy_s(param.szBuf[3], "ReverseCore");
- // Open Process
- if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, // dwDesiredAccess
- FALSE, // bInheritHandle
- dwPID)) ) // dwProcessId
- {
- printf("OpenProcess() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for THREAD_PARAM
- dwSize = sizeof(THREAD_PARAM);
- if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- dwSize, // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[0], // lpBaseAddress
- (LPVOID)¶m, // lpBuffer
- dwSize, // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for ThreadProc()
- dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
- if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- dwSize, // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_EXECUTE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[1], // lpBaseAddress
- (LPVOID)ThreadProc, // lpBuffer
- dwSize, // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !(hThread = CreateRemoteThread(hProcess, // hProcess
- NULL, // lpThreadAttributes
- 0, // dwStackSize
- (LPTHREAD_START_ROUTINE)pRemoteBuf[1], // dwStackSize
- pRemoteBuf[0], // lpParameter
- 0, // dwCreationFlags
- NULL)) ) // lpThreadId
- {
- printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
完整的代码如下。
- // CodeInjection.cpp
- // reversecore@gmail.com
- // http://www.reversecore.com
- #include "windows.h"
- #include "stdio.h"
- typedef struct _THREAD_PARAM
- {
- FARPROC pFunc[2]; // LoadLibraryA(), GetProcAddress()
- char szBuf[4][128]; // "user32.dll", "MessageBoxA", "www.reversecore.com", "ReverseCore"
- } THREAD_PARAM, *PTHREAD_PARAM;
- typedef HMODULE (WINAPI *PFLOADLIBRARYA)
- (
- LPCSTR lpLibFileName
- );
- typedef FARPROC (WINAPI *PFGETPROCADDRESS)
- (
- HMODULE hModule,
- LPCSTR lpProcName
- );
- typedef int (WINAPI *PFMESSAGEBOXA)
- (
- HWND hWnd,
- LPCSTR lpText,
- LPCSTR lpCaption,
- UINT uType
- );
- DWORD WINAPI ThreadProc(LPVOID lParam)
- {
- PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
- HMODULE hMod = NULL;
- FARPROC pFunc = NULL;
- // LoadLibrary()
- hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]); // "user32.dll"
- if( !hMod )
- return 1;
- // GetProcAddress()
- pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]); // "MessageBoxA"
- if( !pFunc )
- return 1;
- // MessageBoxA()
- ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
- return 0;
- }
- BOOL InjectCode(DWORD dwPID)
- {
- HMODULE hMod = NULL;
- THREAD_PARAM param = {0,};
- HANDLE hProcess = NULL;
- HANDLE hThread = NULL;
- LPVOID pRemoteBuf[2] = {0,};
- DWORD dwSize = 0;
- hMod = GetModuleHandleA("kernel32.dll");
- // set THREAD_PARAM
- param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
- param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
- strcpy_s(param.szBuf[0], "user32.dll");
- strcpy_s(param.szBuf[1], "MessageBoxA");
- strcpy_s(param.szBuf[2], "www.reversecore.com");
- strcpy_s(param.szBuf[3], "ReverseCore");
- // Open Process
- if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, // dwDesiredAccess
- FALSE, // bInheritHandle
- dwPID)) ) // dwProcessId
- {
- printf("OpenProcess() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for THREAD_PARAM
- dwSize = sizeof(THREAD_PARAM);
- if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- dwSize, // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[0], // lpBaseAddress
- (LPVOID)¶m, // lpBuffer
- dwSize, // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for ThreadProc()
- dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
- if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- dwSize, // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_EXECUTE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[1], // lpBaseAddress
- (LPVOID)ThreadProc, // lpBuffer
- dwSize, // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !(hThread = CreateRemoteThread(hProcess, // hProcess
- NULL, // lpThreadAttributes
- 0, // dwStackSize
- (LPTHREAD_START_ROUTINE)pRemoteBuf[1], // dwStackSize
- pRemoteBuf[0], // lpParameter
- 0, // dwCreationFlags
- NULL)) ) // lpThreadId
- {
- printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
- BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
- {
- TOKEN_PRIVILEGES tp;
- HANDLE hToken;
- LUID luid;
- if( !OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken) )
- {
- printf("OpenProcessToken error: %u\n", GetLastError());
- return FALSE;
- }
- if( !LookupPrivilegeValue(NULL, // lookup privilege on local system
- lpszPrivilege, // privilege to lookup
- &luid) ) // receives LUID of privilege
- {
- printf("LookupPrivilegeValue error: %u\n", GetLastError() );
- return FALSE;
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if( bEnablePrivilege )
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
- // Enable the privilege or disable all privileges.
- if( !AdjustTokenPrivileges(hToken,
- FALSE,
- &tp,
- sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES) NULL,
- (PDWORD) NULL) )
- {
- printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
- return FALSE;
- }
- if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
- {
- printf("The token does not have the specified privilege. \n");
- return FALSE;
- }
- return TRUE;
- }
- int main(int argc, char *argv[])
- {
- DWORD dwPID = 0;
- if( argc != 2 )
- {
- printf("\n USAGE : %s <pid>\n", argv[0]);
- return 1;
- }
- // change privilege
- if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
- return 1;
- // code injection
- dwPID = (DWORD)atol(argv[1]);
- InjectCode(dwPID);
- return 0;
- }
说到shellcode,我们还可以把ThreadProc()的代码写成汇编的形式,效果是一样的。
- // CodeInjection2.cpp
- // reversecore@gmail.com
- // http://www.reversecore.com
- #include "windows.h"
- #include "stdio.h"
- typedef struct _THREAD_PARAM
- {
- FARPROC pFunc[2]; // LoadLibraryA(), GetProcAddress()
- } THREAD_PARAM, *PTHREAD_PARAM;
- BYTE g_InjectionCode[] =
- {
- 0x55, 0x8B, 0xEC, 0x8B, 0x75, 0x08, 0x68, 0x6C, 0x6C, 0x00,
- 0x00, 0x68, 0x33, 0x32, 0x2E, 0x64, 0x68, 0x75, 0x73, 0x65,
- 0x72, 0x54, 0xFF, 0x16, 0x68, 0x6F, 0x78, 0x41, 0x00, 0x68,
- 0x61, 0x67, 0x65, 0x42, 0x68, 0x4D, 0x65, 0x73, 0x73, 0x54,
- 0x50, 0xFF, 0x56, 0x04, 0x6A, 0x00, 0xE8, 0x0C, 0x00, 0x00,
- 0x00, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x43, 0x6F,
- 0x72, 0x65, 0x00, 0xE8, 0x14, 0x00, 0x00, 0x00, 0x77, 0x77,
- 0x77, 0x2E, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x63,
- 0x6F, 0x72, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x6A, 0x00,
- 0xFF, 0xD0, 0x33, 0xC0, 0x8B, 0xE5, 0x5D, 0xC3
- };
- /*
- 004010ED 55 PUSH EBP
- 004010EE 8BEC MOV EBP,ESP
- 004010F0 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ; ESI = pParam
- 004010F3 68 6C6C0000 PUSH 6C6C
- 004010F8 68 33322E64 PUSH 642E3233
- 004010FD 68 75736572 PUSH 72657375
- 00401102 54 PUSH ESP ; - "user32.dll"
- 00401103 FF16 CALL DWORD PTR DS:[ESI] ; LoadLibraryA("user32.dll")
- 00401105 68 6F784100 PUSH 41786F
- 0040110A 68 61676542 PUSH 42656761
- 0040110F 68 4D657373 PUSH 7373654D
- 00401114 54 PUSH ESP ; - "MessageBoxA"
- 00401115 50 PUSH EAX ; - hMod
- 00401116 FF56 04 CALL DWORD PTR DS:[ESI+4] ; GetProcAddress(hMod, "MessageBoxA")
- 00401119 6A 00 PUSH 0 ; - MB_OK (0)
- 0040111B E8 0C000000 CALL 0040112C
- 00401120 <ASCII> ; - "ReverseCore", 0
- 0040112C E8 14000000 CALL 00401145
- 00401131 <ASCII> ; - "www.reversecore.com", 0
- 00401145 6A 00 PUSH 0 ; - hWnd (0)
- 00401147 FFD0 CALL EAX ; MessageBoxA(0, "www.reversecore.com", "ReverseCore", 0)
- 00401149 33C0 XOR EAX,EAX
- 0040114B 8BE5 MOV ESP,EBP
- 0040114D 5D POP EBP
- 0040114E C3 RETN
- */
- BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
- {
- TOKEN_PRIVILEGES tp;
- HANDLE hToken;
- LUID luid;
- if( !OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken) )
- {
- printf("OpenProcessToken error: %u\n", GetLastError());
- return FALSE;
- }
- if( !LookupPrivilegeValue(NULL, // lookup privilege on local system
- lpszPrivilege, // privilege to lookup
- &luid) ) // receives LUID of privilege
- {
- printf("LookupPrivilegeValue error: %u\n", GetLastError() );
- return FALSE;
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if( bEnablePrivilege )
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
- // Enable the privilege or disable all privileges.
- if( !AdjustTokenPrivileges(hToken,
- FALSE,
- &tp,
- sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES) NULL,
- (PDWORD) NULL) )
- {
- printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
- return FALSE;
- }
- if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
- {
- printf("The token does not have the specified privilege. \n");
- return FALSE;
- }
- return TRUE;
- }
- BOOL InjectCode(DWORD dwPID)
- {
- HMODULE hMod = NULL;
- THREAD_PARAM param = {0,};
- HANDLE hProcess = NULL;
- HANDLE hThread = NULL;
- LPVOID pRemoteBuf[2] = {0,};
- hMod = GetModuleHandleA("kernel32.dll");
- // set THREAD_PARAM
- param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
- param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
- // Open Process
- if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, // dwDesiredAccess
- FALSE, // bInheritHandle
- dwPID)) ) // dwProcessId
- {
- printf("OpenProcess() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for THREAD_PARAM
- if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- sizeof(THREAD_PARAM), // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[0], // lpBaseAddress
- (LPVOID)¶m, // lpBuffer
- sizeof(THREAD_PARAM), // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for ThreadProc()
- if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- sizeof(g_InjectionCode), // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_EXECUTE_READWRITE)) ) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[1], // lpBaseAddress
- (LPVOID)&g_InjectionCode, // lpBuffer
- sizeof(g_InjectionCode), // nSize
- NULL) ) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if( !(hThread = CreateRemoteThread(hProcess, // hProcess
- NULL, // lpThreadAttributes
- 0, // dwStackSize
- (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
- pRemoteBuf[0], // lpParameter
- 0, // dwCreationFlags
- NULL)) ) // lpThreadId
- {
- printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
- int main(int argc, char *argv[])
- {
- DWORD dwPID = 0;
- if( argc != 2 )
- {
- printf("\n USAGE : %s <pid>\n", argv[0]);
- return 1;
- }
- // change privilege
- if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
- return 1;
- // code injection
- dwPID = (DWORD)atol(argv[1]);
- InjectCode(dwPID);
- return 0;
- }
可以看到,_THREAD_PARAM结构体中并不包含字符串成员,并且图中的指令字节数组(g_InjectionCode)替代了用C语言编写的ThreadProc()函数。
逆向工程核心原理读书笔记-代码注入相关推荐
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(一)
简评: 整体看了下代码,其实就是应用层的inline hook, 钩子勾住ntdll.dll里面的ZwQuerySystemInformation函数, xp环境测试成功了,win7测试失败了,不知道 ...
- 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制
我们通过一个示例来练习钩取IE8的InternetConnect函数,用IE8连接指定网站时,使之连接到另一个网站.和以前钩取CreateProcess不同,这次我们钩取更低级的ZwResumeThr ...
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
上一篇文章我们实现的隐藏进程如果重新打开任务管理器或者被隐藏的进程就没有隐藏的效果了.为了弥补这个问题,我们不仅需要钩取当前运行的所有进程,还要钩取将来运行的所有进程.由于所有的进程都是由父进程使用C ...
- 逆向工程核心原理读书笔记-API钩取之计算器显示中文数字
我们通过一个示例来练习向计算机进程插入用户的DLL文件,钩取负责向计算器显示文本的SetWindowTextW,使得计算器中显示中文数字而不是原来的阿拉伯数字.钩取前后的原理图如下所示. 下面我们先测 ...
- 逆向工程核心原理读书笔记-API钩取之记事本小写转大写
我们通过一个示例来练习钩取Notepad.exe的WriteFile,保存文件时将小写字母全部转换为大写字母.下面我们先测试一下代码. 运行notepad.exe并查看PID. 在命令行窗口中输入命令 ...
- 逆向工程核心原理学习笔记(十四):栈帧1
栈帧的话,直接截了一些图,大家看一下就好了,理解起来很简单,就是简单的参数转存. 看完之后,我们需要用一个小程序来进一步学习我们的栈帧了. 下载地址:http://t.cn/RaUSglI 代码写法: ...
- 逆向工程核心原理学习笔记(十三):分析abex' crackme #1 的延伸:将参数压入栈
还是上一次的abex' crackme #1,我们用OD附加看一下. 我们发现在调用这个MessageBox函数的时候,用了4个PUSH指令,我们在后面的注释中可以清楚的看到压入参数的内容. 如果我们 ...
- 逆向工程核心原理学习笔记(九):小端序标记法2
程序地址:http://t.cn/RXnT2pD 我们用OD查看小端序. 代码如下: 我们编译,然后拖进OD查看,直接跳到0x401000入口点. 我们看到几个位置: 由此处我们可以推测后面括号中存放 ...
- 逆向工程核心原理学习笔记(七):总结
首先就是上一节,我们尝试把修改后的代码保存后运行,发现不可以,. 这是由于我们修改的那部分缓冲区造成的. 可执行文件加大再到内存中兵役进程的形式运行并非原封不动的载入内存,而是遵循一定的规则进行,这一 ...
最新文章
- nacos1.0.0 服务管理使用mysql
- 学python用什么系统好-学Python用什么系统?
- 命令行运行jmeter脚本
- soultion of mySQL disk exceeded problem
- 推荐一款专为新手用的Python开发工具
- 原来互联网公司想裁员还能这样玩?
- Hulu面试(或许待更)
- 2021-09-02 linux修改open files数
- 07. Python-异常
- vue项目无法启动,谷歌浏览器报:您与此网站之间建立的连接不安全,实际是cdn服务器过期
- 传销?花生日记罚款7456万元这个微信社群营销分钱模式要知道
- krpano相关笔记
- 武汉伯钧成科技有限公司之行的郁闷感受
- DirectX 9.0笔记]第一章 初始化 Direct3D
- 涅槃重生,力荐大型分布式手册,凤凰架构让你浴火成神,良心分享
- 达梦数据库导入dmp文件
- python中1到100怎么表示_python如何计算1到100的和(用for循环)
- VUE3中 v-for指令用法,列表循环
- 编译器优化故障的测试与定位
- 数学建模笔记(十一):统计模型(MATLAB计算,函数参数解释待补充)
热门文章
- 什么是声明式事务控制
- OAuth2.0授权码认证流程介绍
- 基于xml的方式配置AOP
- 数据库-事务并发操作问题及并发的控制
- 数据库-多条件查询-优先级
- 内核aio_今天来说说令人让人傻傻分不清的BIO,NIO,AIO
- mysql列偏移_MySQL:如何对待分布偏移的数据
- Activemq-In-action(二)
- 语音控制面板 通过linux_在Linux中,通常把设备作为( )来处理.
- 财政指标是什么意思_in the black是“在黑暗中”吗?那in the dark是什么意思?