-
-
未解决 [求助]滴水逆向三期的加壳作业求助 100雪币
-
发表于: 2025-8-19 20:31 476
-
使用zwUnmap或者ntUnmap卸载外壳,壳文件加载在随机地址,比如0xdd0000时,源文件贴在0x400000,卸载壳文件加载的位置后会无法运行.打开源文件随机基址后,壳文件随机加载,比如0xdd0000,同样卸载壳文件加载位置,将源文件贴在0xdd0000这个位置并修复重定位表却可以运行.试了很多种发现只有壳文件卸载后源文件贴在壳文件原来的地址才能运行,不然只要卸载壳文件就运行不起来.这是为什么?卸载壳文件加载的位置后用virtualalloc重新申请该位置内存后也跑不起来.求解答
.
// ShellCode.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<windows.h>
#pragma comment(lib, "WindowsApp.lib")
typedef ULONG(WINAPI* PFNNtUnmapViewOfSection) (HANDLE ProcessHandle, PVOID BaseAddress);
typedef unsigned long(__stdcall* pfZwUnmapViewOfSection)(unsigned long, unsigned long);
DWORD RVATOFOA(LPVOID pFileBuffer, DWORD RVA) {
_IMAGE_DOS_HEADER* DOS_HEADER = (_IMAGE_DOS_HEADER*)pFileBuffer;
_IMAGE_NT_HEADERS* NT_HEADERS = (_IMAGE_NT_HEADERS*)((DWORD)pFileBuffer + DOS_HEADER->e_lfanew);
_IMAGE_SECTION_HEADER* SECTION_HEADER = (_IMAGE_SECTION_HEADER*)((DWORD)pFileBuffer + DOS_HEADER->e_lfanew + 0x4 + sizeof(_IMAGE_FILE_HEADER) + NT_HEADERS->FileHeader.SizeOfOptionalHeader);
if (RVA < SECTION_HEADER->VirtualAddress)return RVA;
for (int i = 0; i < NT_HEADERS->FileHeader.NumberOfSections; i++) {
if (i == NT_HEADERS->FileHeader.NumberOfSections - 1 || (RVA >= (SECTION_HEADER + i)->VirtualAddress && RVA < (SECTION_HEADER + i + 1)->VirtualAddress))
return RVA + (SECTION_HEADER + i)->PointerToRawData - (SECTION_HEADER + i)->VirtualAddress;
}
}
void ChangeImageBase(LPVOID pFileBuffer, DWORD ImageBase) {
_IMAGE_DOS_HEADER* DOS_HEADER = (_IMAGE_DOS_HEADER*)pFileBuffer;
_IMAGE_NT_HEADERS* NT_HEADERS = (_IMAGE_NT_HEADERS*)((DWORD)pFileBuffer + DOS_HEADER->e_lfanew);
_IMAGE_BASE_RELOCATION* BASE_RELOC = (_IMAGE_BASE_RELOCATION*)((DWORD)pFileBuffer + RVATOFOA(pFileBuffer, NT_HEADERS->OptionalHeader.DataDirectory[5].VirtualAddress));
DWORD offset = ImageBase - NT_HEADERS->OptionalHeader.ImageBase;
while (BASE_RELOC->SizeOfBlock || BASE_RELOC->VirtualAddress) {
int NUM = (BASE_RELOC->SizeOfBlock - 0x8) / 2;
for (int i = 0; i < NUM; i++) {
if ((*((WORD*)((DWORD)BASE_RELOC + 0x8) + i) >> 12) == 3) {
*(DWORD*)((DWORD)pFileBuffer + (RVATOFOA(pFileBuffer, BASE_RELOC->VirtualAddress + (*((WORD*)((DWORD)BASE_RELOC + 0x8) + i) & 0x0FFF)))) += offset;
}
}
BASE_RELOC = (_IMAGE_BASE_RELOCATION*)((DWORD)BASE_RELOC + BASE_RELOC->SizeOfBlock);
}
NT_HEADERS->OptionalHeader.ImageBase = ImageBase;
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
_IMAGE_DOS_HEADER* DOS_HEADER = (_IMAGE_DOS_HEADER*)hInstance;
_IMAGE_NT_HEADERS* NT_HEADERS = (_IMAGE_NT_HEADERS*)((DWORD)hInstance + DOS_HEADER->e_lfanew);
_IMAGE_SECTION_HEADER* SECTION_HEADER = (_IMAGE_SECTION_HEADER*)((DWORD)hInstance + DOS_HEADER->e_lfanew + 0x4 + sizeof(_IMAGE_FILE_HEADER) + NT_HEADERS->FileHeader.SizeOfOptionalHeader);
DWORD SECTION_OFFSET = -1;
TCHAR Buffer[256] = {};
wsprintf(Buffer, L"%08x", hInstance);
OutputDebugString(Buffer);
for (int i = 0; i < NT_HEADERS->FileHeader.NumberOfSections; i++) {
if (!strcmp((char*)(SECTION_HEADER + i), ".code")) {
SECTION_OFFSET = i;
break;
}
}
if (SECTION_OFFSET == -1) {
OutputDebugString(TEXT("找不到节\n"));
return 0;
}
//for(int i=0;i<(SECTION_HEADER+SECTION_OFFSET)->)
TCHAR BufferPath[256] = {};
GetModuleFileName(0, BufferPath, 256);
STARTUPINFO si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi = {};
CONTEXT Context;
SECURITY_ATTRIBUTES la_proc = { sizeof(SECURITY_ATTRIBUTES) ,0 ,FALSE};
SECURITY_ATTRIBUTES la_thread = { sizeof(SECURITY_ATTRIBUTES),0,FALSE };
CreateProcess(
BufferPath,
0,
&la_proc,
&la_thread,
FALSE,
CREATE_SUSPENDED,
0,
0,
&si,
&pi
);
//挂起形式创建
Context.ContextFlags = CONTEXT_ALL;
GetThreadContext(pi.hThread,&Context);
DWORD ImageBaseAddr = Context.Ebx + 0x8;
ULONG ImageBase;
HMODULE HLE = LoadLibrary(TEXT("ntdll.dll"));
PFNNtUnmapViewOfSection NtUnmapViewOfSection = (PFNNtUnmapViewOfSection)GetProcAddress(HLE, "NtUnmapViewOfSection");
pfZwUnmapViewOfSection ZwUnmapViewOfSection = (pfZwUnmapViewOfSection)GetProcAddress(HLE, "ZwUnmapViewOfSection");
if (NtUnmapViewOfSection == NULL) {
OutputDebugString(TEXT("找不到\n"));
return 0;
}
ReadProcessMemory(pi.hProcess, (LPVOID)ImageBaseAddr, &ImageBase,4,0);
ZwUnmapViewOfSection((DWORD)pi.hProcess, ImageBase);
wsprintf(BufferPath, L"%x", ImageBase);
OutputDebugString(BufferPath);
//NtUnmapViewOfSection(pi.hProcess, (LPVOID)0x400000);
//NtUnmapViewOfSection(pi.hProcess, (LPVOID)ImageBase);
//卸载壳文件
//----------加密段可直接注释掉------------
DWORD START = (DWORD)((SECTION_HEADER + SECTION_OFFSET)->VirtualAddress + (DWORD)hInstance);
for (int i = 0; i < 0x400; i++) {
*((BYTE*)START + i) = *((BYTE*)START+i) ^ 2;
if (i < 2) {
wsprintf(Buffer,L"%x", *((BYTE*)START + i));
OutputDebugString(Buffer);
}
}
for (int i = 0x400; i < (SECTION_HEADER + SECTION_OFFSET)->SizeOfRawData; i++) {
*((BYTE*)START + i) = *((BYTE*)START + i) ^ 3;
}
//----------加密段可直接注释掉------------
_IMAGE_DOS_HEADER* newDOS_HEADER = (_IMAGE_DOS_HEADER*)((SECTION_HEADER+SECTION_OFFSET)->VirtualAddress + (DWORD)hInstance);
_IMAGE_NT_HEADERS* newNT_HEADERS = (_IMAGE_NT_HEADERS*)((DWORD)newDOS_HEADER + newDOS_HEADER->e_lfanew);
_IMAGE_SECTION_HEADER* newSECTION_HEADER = (_IMAGE_SECTION_HEADER*)((DWORD)newDOS_HEADER + newDOS_HEADER->e_lfanew + 0x4 + sizeof(_IMAGE_FILE_HEADER) + newNT_HEADERS->FileHeader.SizeOfOptionalHeader);
if (!newNT_HEADERS->OptionalHeader.DataDirectory[5].VirtualAddress) {
OutputDebugString(L"没有重定位表我们完蛋了!\n");
}
else {
ChangeImageBase(newDOS_HEADER, ImageBase);
}
wsprintf(BufferPath, L"ImageBase%x", ImageBase);
OutputDebugString(BufferPath);
LPVOID newImageBase = VirtualAllocEx(pi.hProcess, (LPVOID)newNT_HEADERS->OptionalHeader.ImageBase,newNT_HEADERS->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!newImageBase) {
OutputDebugString(TEXT("获取失败!"));
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
//ChangeImageBase(newDOS_HEADER, newImageBase);
return 0;
}
DWORD* num = new DWORD[newNT_HEADERS->OptionalHeader.SizeOfImage];
memset(num, 0, newNT_HEADERS->OptionalHeader.SizeOfImage);
WriteProcessMemory(pi.hProcess, (LPVOID)newNT_HEADERS->OptionalHeader.ImageBase, num, newNT_HEADERS->OptionalHeader.SizeOfImage, 0);
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
WriteProcessMemory(pi.hProcess, (LPVOID)newNT_HEADERS->OptionalHeader.ImageBase, newDOS_HEADER, newNT_HEADERS->OptionalHeader.SizeOfHeaders, 0);
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
//贴头部分
wsprintf(BufferPath, L"%d", newNT_HEADERS->FileHeader.NumberOfSections);
OutputDebugString(BufferPath);
for (int i = 0; i < newNT_HEADERS->FileHeader.NumberOfSections; i++) {
CHAR str[256] = {};
WriteProcessMemory(pi.hProcess, (LPVOID)(newNT_HEADERS->OptionalHeader.ImageBase + (newSECTION_HEADER +i)->VirtualAddress), (LPVOID)((DWORD)newDOS_HEADER +(newSECTION_HEADER + i)->PointerToRawData), (newSECTION_HEADER + i)->SizeOfRawData, 0);
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
sprintf_s(str,256, "%d %s已写入!\n",i+1,(newSECTION_HEADER + i)->Name);
OutputDebugStringA(str);
}
//贴段部分
Context.Eax = newNT_HEADERS->OptionalHeader.AddressOfEntryPoint + newNT_HEADERS->OptionalHeader.ImageBase;
//修改context的eax
wsprintf(BufferPath, L"%x", Context.Eax);
OutputDebugString(BufferPath);
DWORD dwImageBase = newNT_HEADERS->OptionalHeader.ImageBase;
WriteProcessMemory(pi.hProcess,
(LPVOID)(Context.Ebx + 8), (LPCVOID)&dwImageBase, sizeof(PVOID), NULL);
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
SetThreadContext(pi.hThread, &Context);
//设置context
wsprintf(BufferPath, L"%d", GetLastError());
OutputDebugString(BufferPath);
//ReadProcessMemory(pi.hProcess, (LPVOID)newNT_HEADERS->OptionalHeader.ImageBase, BufferPath, 256, 0);
//wsprintf(BufferPath, L"%d", GetLastError());
//OutputDebugString(BufferPath);
ResumeThread(pi.hThread);
MessageBox(0, TEXT("线程启动"), 0, 0);
return 0;
}[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
赞赏
赞赏
雪币:
留言: