其他
VC黑防日记:DLL隐藏和逆向(续)
大家都知道,在x86的平台上Windows操作系统为每个进程描述了一个完整的4G的地址空间,这4G空间由低位2G的用户地址空间和高位2G的系统地址空间构成。每个进程的用户地址空间是相互隔离的,不可见的。但是系统地址空间是各个进程间共享的,对于进程有不同的视图。用户的私有的数据代码还有加载的动态链接库(DLL)都存放在用户地址空间中。现在有个问题是,总要有个地方记录着这2G地址空间,到底那些被预留了,那些被提交了,那些被访问了吧。还有个问题就是,对于程序来讲,地址不是连续的,是分段的。代码段、数据段、堆、栈等等。可是进程的空间是连续的,从0x0000000到0x7FFFFFF。总要有个数据结构描述程序的各个段对应那段地址空间。这两个重要任务就交个了VAD,即虚拟地址描述符(Virtual Address Descriptor)。
VAD组织成了一个AVL自平衡二叉树(参考Mark Russinovich的《深入解析Windows操作系统》),这种组织方式完全是方便快速查找。树中的每一个节点代表了一段虚拟地址空间。所以程序的代码段,数据段,堆段都会各种占用一个或多个VAD节点,由一个MMVAD结构完整描述。
内核空间并不受VAD的管理。
https://baike.baidu.com/item/%E8%99%9A%E6%8B%9F%E5%9C%B0%E5%9D%80%E6%8F%8F%E8%BF%B0%E7%AC%A6/295257?fr=aladdin
char szExePath[MAX_PATH] = "C:\\Users\\86186\\Desktop\\mydll.dll";
HANDLE hFile = CreateFile(szExePath, GENERIC_ALL, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
//获得PE文件句柄
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
//创建一个新的文件映射内核对象
PVOID pbFile = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//将一个文件映射对象映射到内存,得到指向映射到内存的第一个字节的指针pbFile
if (INVALID_HANDLE_VALUE == hFile || NULL == hMapping || NULL == pbFile)
{
printf("\n\t---------- The File Inexistence! ----------\n");
if (NULL != pbFile)
{
UnmapViewOfFile(pbFile);
}
if (NULL != hMapping)
{
CloseHandle(hMapping);
}
if (INVALID_HANDLE_VALUE != hFile)
{
CloseHandle(hFile);
}
return 0;
}
//pDosHeader指向DOS头起始位置
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbFile;
printf("PE Header e_lfanew:0x%x\n", pDosHeader->e_lfanew);
//计算PE头位置
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pbFile + pDosHeader->e_lfanew);
//计算DLL模块镜像大小
DWORD dwSizeOfImage = (DWORD)pNTHeader->OptionalHeader.SizeOfImage;
printf("SizeOfImage: 0x%08X\n", dwSizeOfImage);
VirtualAllocEx(hProcess, NULL, dwSizeOfImage, MEM_COMMIT, PAGE_READWRITE);
BOOL VirtualProtectEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
//保存数组
BYTE code[] = { 0 };
DWORD lp_copy = (DWORD)lpaddress;
DWORD lp_start = addr_start;
for (int i = 0; i < dwSizeOfImage; i++, lp_start++, lp_copy++) {
ReadProcessMemory(hProcess, (LPCVOID)lp_start, code, 1, NULL);
WriteProcessMemory(hProcess, (LPVOID)lp_copy, code, 1, NULL);
}
printf("原地址 = 0x%x 拷贝地址 = 0x%x\n", addr_start, lpaddress);
MessageBox(NULL, "拷贝完成!", "Cap", MB_OK);
UnInject(Pid, DLL路径);
int main()
{
const char* a = "C:\\Users\\86186\\Desktop\\mydll.dll";
HANDLE hToken = NULL;
//打开当前进程的访问令牌
int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
if (hRet)
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
//取得描述权限的LUID
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//调整访问令牌的权限
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
CloseHandle(hToken);
}
char szExePath[MAX_PATH] = "C:\\Users\\86186\\Desktop\\mydll.dll";
HANDLE hFile = CreateFile(szExePath, GENERIC_ALL, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
//获得PE文件句柄
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
//创建一个新的文件映射内核对象
PVOID pbFile = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//将一个文件映射对象映射到内存,得到指向映射到内存的第一个字节的指针pbFile
if (INVALID_HANDLE_VALUE == hFile || NULL == hMapping || NULL == pbFile)
{
printf("\n\t---------- The File Inexistence! ----------\n");
if (NULL != pbFile)
{
UnmapViewOfFile(pbFile);
}
if (NULL != hMapping)
{
CloseHandle(hMapping);
}
if (INVALID_HANDLE_VALUE != hFile)
{
CloseHandle(hFile);
}
return 0;
}
//pDosHeader指向DOS头起始位置
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbFile;
printf("PE Header e_lfanew:0x%x\n", pDosHeader->e_lfanew);
//计算PE头位置
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pbFile + pDosHeader->e_lfanew);
//计算DLL模块镜像大小
DWORD dwSizeOfImage = (DWORD)pNTHeader->OptionalHeader.SizeOfImage;
printf("SizeOfImage: 0x%08X\n", dwSizeOfImage);
UnmapViewOfFile(pbFile);
CloseHandle(hMapping);
CloseHandle(hFile);
Inject(GetProcessIDByName("代码注入器.exe"), (char*)a);
MessageBox(NULL, "注入完成!", "Cap", MB_OK);
int Pid = 0;
while (1)
{
Pid = GetProcessIDByName("代码注入器.exe");
if (Pid > 0)
{
MessageBox(NULL, "检测到进程,点击确定开始申请内存!", "Cap", MB_OK);
break;
}
}
//申请内存
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
DWORD dwOldProtect;
LPVOID lpaddress = VirtualAllocEx(hProcess, NULL, dwSizeOfImage, MEM_COMMIT, PAGE_READWRITE);
printf("分配地址:0x%x\n",lpaddress);
VirtualProtectEx(hProcess, lpaddress, dwSizeOfImage + 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
DWORD addr_start = 0;
while (1)
{
addr_start = GetProcessModuleHandleByName(Pid, "mydll.dll");
if (addr_start > 0)
{
MessageBox(NULL, "检测到DLL被注入了,点击确定开始拷贝DLL!", "Cap", MB_OK);
break;
}
}
//保存数组
BYTE code[] = { 0 };
DWORD lp_copy = (DWORD)lpaddress;
DWORD lp_start = addr_start;
for (int i = 0; i < dwSizeOfImage; i++, lp_start++, lp_copy++) {
ReadProcessMemory(hProcess, (LPCVOID)lp_start, code, 1, NULL);
WriteProcessMemory(hProcess, (LPVOID)lp_copy, code, 1, NULL);
}
printf("原地址 = 0x%x 拷贝地址 = 0x%x\n", addr_start, lpaddress);
MessageBox(NULL, "拷贝完成!", "Cap", MB_OK);
//真正去卸载
UnInject(GetProcessIDByName("代码注入器.exe"), (char*)a);
printf("原地址 = 0x%x \n", addr_start);
//还原DLL镜像至原地址
DWORD VirtualAddress = lpaddress;
VirtualFreeEx(hProcess, addr_start, dwSizeOfImage + 1, MEM_RELEASE);
DWORD returnValue = VirtualAllocEx(hProcess, addr_start, dwSizeOfImage + 1, MEM_COMMIT, PAGE_READWRITE);
int error1 = GetLastError();
printf("the value = %d error = %d \n", returnValue, error1);
MessageBox(NULL, "原内存地址恢复完成!", "Cap", MB_OK);
VirtualProtectEx(hProcess, addr_start, dwSizeOfImage + 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
for (int i = 0; i < dwSizeOfImage; i++, addr_start++, VirtualAddress++) {
ReadProcessMemory(hProcess, (LPCVOID)VirtualAddress, code, 1, NULL);
WriteProcessMemory(hProcess, (LPVOID)addr_start, code, 1, NULL);
}
MessageBox(NULL, "还原完成!DLL隐藏完成!", "Cap", MB_OK);
getchar();
return 0;
}
DWORD returnValue = VirtualAllocEx(hProcess, addr_start, dwSizeOfImage + 1, MEM_COMMIT, PAGE_READWRITE);
int error1 = GetLastError();
printf("the value = %d error = %d \n", returnValue, error1);
MessageBox(NULL, "原内存地址恢复完成!", "Cap", MB_OK);
看雪ID:小迪xiaodi
https://bbs.pediy.com/user-680946.htm
推荐文章++++
好书推荐