1

来源:互联网 发布:外贸出口的数据 编辑:程序博客网 时间:2024/06/05 07:52
void C网络流量监控Dlg::OnBnClickedButtonfrushprocesslist()
{
m_ProcessList.DeleteAllItems();


PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
//定义进程信息结构


HANDLE hProcessShot;
hProcessShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessShot == INVALID_HANDLE_VALUE)
{
m_Log.AddString(L"获取进程列表失败");
return;
}
// 创建系统当前进程快照


if (Process32First(hProcessShot,&pe32))
{
for (int i = 0;Process32Next(hProcessShot, &pe32);i++)
{
this->m_ProcessList.InsertItem(i, pe32.szExeFile);
WCHAR szStrTemp[10];
StringCchPrintf(szStrTemp, 100, L"%d", pe32.th32ProcessID);
this->m_ProcessList.SetItemText(i, 1, szStrTemp);
StringCchPrintf(szStrTemp, 100, L"%d", pe32.cntThreads);
this->m_ProcessList.SetItemText(i, 2, szStrTemp);
}
}
//遍历进程快照


m_Log.AddString(L"刷新进程列表成功");
CloseHandle(hProcessShot);
// TODO: 在此添加控件通知处理程序代码
}


HMODULE C网络流量监控Dlg::fnGetProcessBase(DWORD dwProcessID)
{
//获取进程基址
HANDLE hSnapShot;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
this->m_Log.AddString(L"无法创建快照");
return NULL;
}
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(ModuleEntry32);
if (Module32First(hSnapShot, &ModuleEntry32))
{
do 
{
WCHAR szExt[5];
wcscpy(szExt, ModuleEntry32.szExePath + wcslen(ModuleEntry32.szExePath) - 4);
for (int i = 0;i < 4;i++)
{
if ((szExt[i] >= 'a')&&(szExt[i] <= 'z'))
{
szExt[i] = szExt[i] - 0x20;
}
}
if (!wcscmp(szExt, L".EXE"))
{
m_Log.AddString(L"选中进程:");
m_Log.AddString(ModuleEntry32.szExePath);
CloseHandle(hSnapShot);
return ModuleEntry32.hModule;
}
} while (Module32Next(hSnapShot, &ModuleEntry32));
}
this->m_Log.AddString(L"获取进程基址失败");
CloseHandle(hSnapShot);
return NULL;
}




void C网络流量监控Dlg::OnBnClickedButtonstart()
{
int iCur;
iCur = m_ProcessList.GetNextItem(-1, LVNI_SELECTED);
if (iCur == -1)
{
this->m_Log.AddString(L"未选择进程");
return;
}
WCHAR szProcessID[10];
m_ProcessList.GetItemText(iCur, 1, szProcessID, 10);
DWORD dwProcessID;
swscanf(szProcessID, L"%d", &dwProcessID);
HMODULE hModule;
hModule = fnGetProcessBase(dwProcessID);
if (!hModule)
  {
return;
  }
PBYTE pBase = fnMapProcess(dwProcessID, hModule);
DWORD dwFunctionAddressInImport;
dwFunctionAddressInImport = fnGetFunctionAddress(pBase, "USER32.DLL", "MessageBoxW");
fnHookAPI(dwProcessID, (DWORD)pBase, (DWORD)(PBYTE)hModule, dwFunctionAddressInImport);
// TODO: 在此添加控件通知处理程序代码
}


PBYTE C网络流量监控Dlg::fnMapProcess(DWORD dwProcessID, HMODULE hModule)
{
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (!hProcess)
{
m_Log.AddString(L"无法打开进程");
return NULL;
}
//打开进程


IMAGE_DOS_HEADER DosHeader;
DWORD dwSizeOfRead;
if (!ReadProcessMemory(hProcess, hModule, &DosHeader, sizeof(DosHeader), &dwSizeOfRead))
{
m_Log.AddString(L"无法读取目标进程");
CloseHandle(hProcess);
return NULL;
}
//读取DOS文件头


PIMAGE_NT_HEADERS pNTHeaders = new IMAGE_NT_HEADERS;
if (!ReadProcessMemory(hProcess, (PBYTE)hModule + DosHeader.e_lfanew, pNTHeaders, sizeof(IMAGE_NT_HEADERS), &dwSizeOfRead))
{
m_Log.AddString(L"无法读取目标进程");
CloseHandle(hProcess);
return NULL;
}
//读取NT文件头
DWORD dwe = GetLastError();
DWORD dwSizeOfImage;
dwSizeOfImage = pNTHeaders->OptionalHeader.SizeOfImage;
//读取映像大小


PBYTE pBase;
pBase = new BYTE[dwSizeOfImage];
if (!pBase)
{
m_Log.AddString(L"无法创建缓冲区");
CloseHandle(hProcess);
return NULL;
}
if (!ReadProcessMemory(hProcess, hModule, pBase, dwSizeOfImage, &dwSizeOfRead))
{
m_Log.AddString(L"无法读取目标进程");
CloseHandle(hProcess);
return NULL;
}
CloseHandle(hProcess);
m_Log.AddString(L"映射目标进程成功");
return pBase;
}


DWORD C网络流量监控Dlg::fnGetFunctionAddress(PBYTE pBase, LPCSTR szDllName, LPCSTR szFunctionName)
{
//获取目标进程输入表内函数调用地址
PIMAGE_DOS_HEADER DosHeader;
DosHeader = (PIMAGE_DOS_HEADER)pBase;
PIMAGE_NT_HEADERS NTHeaders;
NTHeaders = (PIMAGE_NT_HEADERS)(pBase + DosHeader->e_lfanew);
DWORD dwImportVA;
dwImportVA = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD dwImportSize;
dwImportSize = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
PIMAGE_IMPORT_DESCRIPTOR pImportDirectory;
DWORD dwNumberOfImportDirectory;
dwNumberOfImportDirectory = dwImportSize / sizeof(IMAGE_IMPORT_DESCRIPTOR);
pImportDirectory = (PIMAGE_IMPORT_DESCRIPTOR)(pBase + dwImportVA);
//获取输入表信息


for (int i = 0;i < dwNumberOfImportDirectory;i++)
{
// if (!pImportDirectory[i].FirstThunk)
// {
// 
// break;
// }
PBYTE pDllName;
pDllName = pBase + pImportDirectory[i].Name;
for (int j = 0;pDllName[j];j++)
{
if ((pDllName[j] >= 'a')&&(pDllName[j] <= 'z'))
{
pDllName[j] = pDllName[j] - 0x20;
}
}
if (!strcmp((char*)pDllName, szDllName))
{
PIMAGE_THUNK_DATA pThunkData;
pThunkData = (PIMAGE_THUNK_DATA)(pBase + pImportDirectory[i].OriginalFirstThunk);
DWORD dwNumberOfThunk;
dwNumberOfThunk = 0;
PIMAGE_IMPORT_BY_NAME pImportByName;
for (int j = 0;pThunkData[j].u1.Ordinal;j++)
{
pImportByName = (PIMAGE_IMPORT_BY_NAME)(pBase + pThunkData[j].u1.AddressOfData);
if (!strcmp((char*)&pImportByName->Name, szFunctionName))
{
dwNumberOfThunk = j;
break;
}
}
PIMAGE_THUNK_DATA pFirstThunk;
pFirstThunk = (PIMAGE_THUNK_DATA)(pBase + pImportDirectory[i].FirstThunk);
DWORD dwFunctionAddress;
return (DWORD)(PBYTE)&pFirstThunk[dwNumberOfThunk].u1.Function - (DWORD)pBase;
}
}
return NULL;
}


BOOL C网络流量监控Dlg::fnHookAPI(DWORD dwProcessID, DWORD dwBase, DWORD pBase, DWORD dwOffsetInImport)
{
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (hProcess == INVALID_HANDLE_VALUE)
{
m_Log.AddString(L"无法打开目标进程");
return FALSE;
}
//打开目标进程


DWORD dwProtect;
if (!VirtualProtectEx(hProcess, (LPVOID)(LPVOID)(pBase + dwOffsetInImport), 4, PAGE_EXECUTE_READWRITE, &dwProtect))
{
int a = GetLastError();
m_Log.AddString(L"无法修改目标进程空间属性");
return FALSE;
}
//修改目标进程输入表的内存属性为可写


PBYTE pNewFunction = (PBYTE)VirtualAllocEx(hProcess, NULL, REMOTE_PROCESS_BUFFER_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pNewFunction)
{
m_Log.AddString(L"无法在目标进程空间建立缓冲区");
return FALSE;
}
//在目标进程中申请一段内存来防止监测代码
DWORD dwSizeOfRead;
DWORD dwOldFunCtion;
if (!ReadProcessMemory(hProcess, (LPVOID)(LPVOID)(pBase + dwOffsetInImport), &dwOldFunCtion, sizeof(dwOldFunCtion), &dwSizeOfRead))
{
m_Log.AddString(L"无法写入目标进程空间");
return FALSE;
}
//读取原函数调用地址


DWORD dwSizeOfWrite;
if (!WriteProcessMemory(hProcess, (LPVOID)(pBase + dwOffsetInImport), &pNewFunction, 4, &dwSizeOfWrite))
{
m_Log.AddString(L"无法写入目标进程空间");
return FALSE;
}
//修改输入表中的函数调用地址

PBYTE pBuffer = new BYTE[REMOTE_PROCESS_BUFFER_SIZE];
if (!pBuffer)
{
m_Log.AddString(L"无法建立本地缓冲区");
return FALSE;
}
//建立本地缓冲区


FillMemory(pBuffer, REMOTE_PROCESS_BUFFER_SIZE, 0x90);
//在缓冲区里的填充nop指令来容错


pBuffer[0x500] = 0xE9;
*(PDWORD)(pBuffer + 0x500 + 1) = dwOldFunCtion - 0x500 - (DWORD)pNewFunction - 5;
//设置跳转指令


BYTE CodeStart[] = {0x60, 0x81, 0xEC, 0x00, 0x10, 0x00, 0x00};
// 60                  pushad
// 81EC 00100000       sub     esp, 1000
CopyMemory(pBuffer, CodeStart, sizeof(CodeStart));
//保存现场代码




BYTE CodeEnd[] = {0x61, 0x81, 0xC4, 0x00, 0x10, 0x00, 0x00};
// 81C4 00100000       add     esp, 1000
// 61                  popad
CopyMemory(pBuffer + 0x500 - sizeof(CodeEnd), CodeEnd, sizeof(CodeEnd));
//恢复现场代码


CopyMemory(pBuffer + 0x600, "Monster.dll", strlen("Monster.dll") + 1);
CopyMemory(pBuffer + 0x620, "Function", strlen("Function") + 1);
//写入所要用到的字符串


DWORD dwLoadLibrary;
dwLoadLibrary = fnGetFunctionAddress((PBYTE)dwBase, "KERNEL32.DLL", "LoadLibraryA");
DWORD dwGetProcAddress;
dwGetProcAddress = fnGetFunctionAddress((PBYTE)dwBase, "KERNEL32.DLL", "GetProcAddress");
//获取所要用到的函数地址


BYTE CodeLoadDll[] =
{
0x68, 0x05, 0x28, 0x2C, 0x00, 0xFF, 0x15, 0x11, 0x11, 0x11, 
0x11, 0x68, 0x11, 0x11, 0x11, 0x11, 0x50, 0xFF, 0x15, 0x22, 
0x22, 0x22, 0x22, 0x8B, 0x9C, 0x24, 0x2C, 0x10, 0x00, 0x00, 
0x53, 0x8B, 0x9C, 0x24, 0x28, 0x10, 0x00, 0x00, 0x53, 0xFF, 
0xD0, 0x83, 0xC4, 0x08
};
// 68 05282C00      push    002C2805                         ;  字符串“Monster.dll”的地址
// FF15 11111111    call    dword ptr [11111111]             ;  11111111是算出来的输入表中的LoadLibrary函数的地址
// 68 11111111      push    11111111                         ;  字符串“Function”的地址
// 50               push    eax                              ;  加载后的Monster.dll库的基址
// FF15 22222222    call    dword ptr [22222222]             ;  22222222是算出来的输入表中的GetProcAddress函数的地址
// 8B9C24 2C100000  mov     ebx, dword ptr [esp+102C]        ;  获取缓冲区长度
// 53               push    ebx                              ;  压入缓冲区长度
// 8B9C24 28100000  mov     ebx, dword ptr [esp+1028]        ;  获取缓冲区地址
// 53               push    ebx                              ;  压入缓冲区地址
// FFD0             call    eax                              ;  调用Function
// 83C4 08          add     esp, 8                           ;  恢复堆栈




CopyMemory(pBuffer + 0x200, CodeLoadDll, sizeof(CodeLoadDll));
//写入加载检测模块的代码


DWORD dwAddress;
dwAddress = (DWORD)pNewFunction + 0x600;
CopyMemory(pBuffer + 0x200 + 0x01, &dwAddress, sizeof(dwAddress));//字符串“Monster.dll”的地址
dwAddress = (DWORD)pNewFunction + 0x620;
CopyMemory(pBuffer + 0x200 + 0x0C, &dwAddress, sizeof(dwAddress));//字符串“Monster.dll”的地址
dwAddress = (DWORD)pBase + dwLoadLibrary;
CopyMemory(pBuffer + 0x200 + 0x07, &dwAddress, sizeof(dwAddress));//LoadLibrary函数的地址
dwAddress = (DWORD)pBase + dwGetProcAddress;
CopyMemory(pBuffer + 0x200 + 0x13, &dwAddress, sizeof(dwAddress));//GetProcAddress函数的地址
//修正所要使用到的地址


if (!WriteProcessMemory(hProcess, (LPVOID)pNewFunction, pBuffer, REMOTE_PROCESS_BUFFER_SIZE, &dwSizeOfWrite))
{
m_Log.AddString(L"无法写入目标进程空间");
return FALSE;
}
//将ShellCode写入目标进程


m_Log.AddString(L"成功修改目标进程");
return TRUE;
}


BOOL C网络流量监控Dlg::fnGetPrivileges()
{
//提升当前进程的访问权限
HANDLE hCurrentProcess;
hCurrentProcess = GetCurrentProcess();
HANDLE hProcessToken;
if (!OpenProcessToken(hCurrentProcess, TOKEN_ALL_ACCESS, &hProcessToken))
{
m_Log.AddString(L"无法获取当前进程令牌");
return FALSE;
}
LUID luid;
LPWSTR lpszPrivilege = SE_DEBUG_NAME;
if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
m_Log.AddString(L"无法查看当前进程令牌");
return FALSE; 
}
TOKEN_PRIVILEGES TokenPrivilileges;
TokenPrivilileges.PrivilegeCount = 1;
TokenPrivilileges.Privileges[0].Luid = luid;
TokenPrivilileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hProcessToken, FALSE, &TokenPrivilileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
{
m_Log.AddString(L"修改当前进程令牌失败");
return FALSE;
}
m_Log.AddString(L"修改当前进程访问令牌成功");
return TRUE;
}