博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ProcessInject(dll)
阅读量:6087 次
发布时间:2019-06-20

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

原理:

通过以挂起的方式创建进程对其注入。

#include 
#include
#include
#include
typedef struct Param{ DWORD year; DWORD Month; DWORD Day; FARPROC pFun[2];}Param,*pParam;void _declspec(naked) AddTimelimit(pParam param){ _asm { pushfd push eax push ecx push edx push ebx sub esp, 0x18 lea eax, ss:[esp + 0x6] push eax mov ebx,[esp+0x34] //保存param结构体指针 call ds:[ebx+0xc] lea eax, ss : [esp + 0x6] mov cx, word ptr ss : [esp + 0x6] mov word ptr ss : [esp], cx mov cx, word ptr ss : [esp + 0x8] mov word ptr ss : [esp + 2], cx mov cx, word ptr ss : [esp + 0xc] mov word ptr ss : [esp + 4], cx mov eax, ss : [ebx] mov ecx, ss : [ebx + 0x4] mov edx, ss : [ebx + 0x8] cmp word ptr ss : [esp], ax ja _Label_exit cmp word ptr ss : [esp + 2], cx ja _Label_exit cmp word ptr ss : [esp + 4], dx ja _Label_exit add esp, 0x18 pop ebx pop edx pop ecx pop eax popfd retn _Label_exit : push 0 call ds : [ebx + 0x10] retn }} //code的原型BYTE code[] = { 0x9C,0x68,0x00,0x00,0x00,0x00,0x50,0x51,0x52,0x53,0x83,0xEC,0x18,0x36,0x8D, 0x44,0x24,0x06,0x50,0x8B,0x5C,0x24,0x2C,0x3E,0xFF,0x53,0x0C,0x36,0x8D,0x44,0x24,0x06,0x36,0x66,0x8B, 0x4C,0x24,0x06,0x36,0x66,0x89,0x0C,0x24,0x36,0x66,0x8B,0x4C,0x24,0x08,0x36, 0x66,0x89,0x4C,0x24,0x02,0x36,0x66,0x8B,0x4C,0x24,0x0C,0x36,0x66,0x89,0x4C, 0x24,0x04,0x36,0x8B,0x03,0x36,0x8B,0x4B,0x04,0x36,0x8B,0x53,0x08,0x36,0x66, 0x39,0x04,0x24,0x77,0x1E,0x36,0x66,0x39,0x4C,0x24,0x02,0x77,0x16,0x36,0x66, 0x39,0x54,0x24,0x04,0x77,0x0E,0x83,0xC4,0x18,0x5B,0x5A,0x59,0x58,0x9D,0x9D, 0x55,0x8B,0xEC,0xE9,0x00,0x00,0x00,0x00,0x6A,0x00,0x3E,0xFF,0x53,0x10,0xC2,0x04,0x00};BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) //提升程序权限{ TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) //获取令牌句柄 { _tprintf(TEXT("OpenProcessToken error : %u\n"), GetLastError()); return FALSE; } LookupPrivilegeValue(NULL, lpszPrivilege, &luid); //获取指定权限的LUID tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; if (!AdjustTokenPrivileges(hToken, //令牌句柄 FALSE, //FALSE则修改权限 &tp, //令牌权限的结构(包括LUID和tp中的数组个数吗) sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { _tprintf(TEXT("AdjustTokenPrivileges error : %u\n"), GetLastError()); return FALSE; } //调整进程的权限 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { _tprintf(TEXT("The Token does not have the specified privilege. \n")); return FALSE; } return TRUE;}void main(){ STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; LPVOID pRemoteParam,pRemoteFun, pBuf_user32; Param param = {0}; DWORD dwBufSize,dwTemp; BYTE mbxBuffer[5] = { 0 }, Buf_user32[] = "user32.dll", jmpcode[5] = { 0xE9,0,0,0,0 }, shellcode[100] = { 0x50,0x9C,0x68,0x00,0x00,0x1C,0x00,0xE8,0xC4,0xD8,0xDC,0x75,0xE8, 0x0F,0x1A,0x79,0x75,0x50,0xE8,0xE9,0xEC,0xDC,0x75,0x9D,0x58,0xE9, 0xD3,0xAE,0xAD,0x77 }; FARPROC Address_mbx = GetProcAddress(LoadLibraryA("user32.dll") , "CreateWindowExA"); DWORD OldProtect = 0; BYTE *pShellcode; param.year = 2018; param.Month = 2; param.Day = 1; param.pFun[0] = GetProcAddress(GetModuleHandle("kernel32.dll"),"GetLocalTime"); param.pFun[1] = GetProcAddress(GetModuleHandle("kernel32.dll"), "ExitProcess"); SetPrivilege(SE_DEBUG_NAME, TRUE); CreateProcessA("需要挂起的程序路径", NULL, NULL,NULL,NULL,CREATE_SUSPENDED,NULL,NULL,&si,&pi); //写入参数到目标进程 dwBufSize = sizeof(param); pRemoteParam = VirtualAllocEx(pi.hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(pi.hProcess,pRemoteParam,(LPVOID)¶m,dwBufSize,NULL); //写入shellcode到目标进程 dwBufSize = 127; pRemoteFun = VirtualAllocEx(pi.hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(&code[2], &pRemoteParam, 4); dwTemp = (DWORD)Address_mbx + 5 - (DWORD)pRemoteFun - 113 - 5; memcpy(&code[114], &dwTemp, 4); WriteProcessMemory(pi.hProcess, pRemoteFun, (LPVOID)code, dwBufSize, NULL); //不sleep就会出现读取不到的297错误 Sleep(50); //获取线程上下文 CONTEXT ct = { 0 }; ct.ContextFlags = CONTEXT_CONTROL; GetThreadContext(pi.hThread, &ct); printf("ct.eip = %X", ct.Eip); //读取挂起位置,供写入shellcode使用 dwBufSize = sizeof(Buf_user32); pBuf_user32 = VirtualAllocEx(pi.hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(pi.hProcess, pBuf_user32, (LPVOID)Buf_user32, dwBufSize, NULL); //为shellcode分配100字节空间并写入 pShellcode = (BYTE *)VirtualAllocEx(pi.hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE); dwTemp = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA") - (DWORD)pShellcode - 5 -7; //push eax memcpy(&shellcode[3],&pBuf_user32,4); //call LoadlibraryA memcpy(&shellcode[8], &dwTemp, 4); //pushfd dwTemp = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetCurrentThread") - (DWORD)pShellcode - 5 - 12; //push add_of_user32.dll memcpy(&shellcode[13], &dwTemp, 4); dwTemp = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "SuspendThread") - (DWORD)pShellcode - 5 - 18; memcpy(&shellcode[19], &dwTemp, 4); dwTemp = ct.Eip - 5 - (DWORD)pShellcode - 25; memcpy(&shellcode[26],&dwTemp,4); WriteProcessMemory(pi.hProcess,pShellcode,shellcode,100,NULL); ct.Eip = (DWORD)pShellcode; SetThreadContext(pi.hThread,&ct); ResumeThread(pi.hThread); Sleep(50); VirtualProtectEx(pi.hProcess,(LPVOID)Address_mbx,10,PAGE_EXECUTE_READWRITE,&OldProtect); //printf("err = %d", GetLastError()); ReadProcessMemory(pi.hProcess, (LPVOID)Address_mbx,(LPVOID)mbxBuffer,10,NULL); //printf("err = %d", GetLastError()); DWORD offset = (DWORD)pRemoteFun - (DWORD)Address_mbx - 5; memcpy(&jmpcode[1], &offset, 4); WriteProcessMemory(pi.hProcess,(LPVOID)Address_mbx,jmpcode,5,NULL); ResumeThread(pi.hThread); //恢复shellcode里挂起的线程}

// ProcessInject.h

#pragma once// ProcessInject 对话框class ProcessInject : public CDialogEx{    DECLARE_DYNAMIC(ProcessInject)public:    ProcessInject(CWnd* pParent = NULL);   // 标准构造函数    virtual ~ProcessInject();// 对话框数据    enum { IDD = IDD_DIALOG3 };protected:    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持    DECLARE_MESSAGE_MAP()public:    CString m_strExePath;    CString m_strDllPath;    afx_msg void OnBnClickedInject();    afx_msg void OnBnClickedFreemem();    afx_msg void OnBnClickedButton3();    afx_msg void OnBnClickedButton4();};

// ProcessInject.cpp

// ProcessInject.cpp : 实现文件//#include "stdafx.h"#include "MyInjectTool.h"#include "ProcessInject.h"#include "afxdialogex.h"//ShellCode结构体//结构必须字节对齐1#pragma pack(1)  typedef struct _INJECT_CODE{    BYTE  byPUSH;    DWORD dwPUSH_VALUE;    BYTE  byPUSHFD;    BYTE  byPUSHAD;    BYTE  byMOV_EAX;          //mov eax, addr szDllpath    DWORD dwMOV_EAX_VALUE;    BYTE  byPUSH_EAX;         //push eax    BYTE  byMOV_ECX;          //mov ecx, LoadLibrary    DWORD dwMOV_ECX_VALUE;    WORD  wCALL_ECX;          //call ecx    BYTE  byPOPAD;    BYTE  byPOPFD;    BYTE  byRETN;    CHAR  szDllPath[MAX_PATH];}INJECT_CODE, *PINJECT_CODE;#pragma pack()  // ProcessInject 对话框IMPLEMENT_DYNAMIC(ProcessInject, CDialogEx)ProcessInject::ProcessInject(CWnd* pParent /*=NULL*/)    : CDialogEx(ProcessInject::IDD, pParent)    , m_strExePath(_T(""))    , m_strDllPath(_T("")){}ProcessInject::~ProcessInject(){}void ProcessInject::DoDataExchange(CDataExchange* pDX){    CDialogEx::DoDataExchange(pDX);    DDX_Text(pDX, IDC_EDIT1, m_strExePath);    DDX_Text(pDX, IDC_EDIT2, m_strDllPath);}BEGIN_MESSAGE_MAP(ProcessInject, CDialogEx)    ON_BN_CLICKED(IDC_INJECT, &ProcessInject::OnBnClickedInject)    ON_BN_CLICKED(IDC_FREEMEM, &ProcessInject::OnBnClickedFreemem)    ON_BN_CLICKED(IDC_BUTTON3, &ProcessInject::OnBnClickedButton3)    ON_BN_CLICKED(IDC_BUTTON4, &ProcessInject::OnBnClickedButton4)END_MESSAGE_MAP()// ProcessInject 消息处理程序HANDLE g_hProcess1 = NULL;LPVOID g_lpBuffer1 = NULL;void ProcessInject::OnBnClickedInject(){    // TODO:  在此添加控件通知处理程序代码    // TODO:  在此添加控件通知处理程序代码    BOOL bRet = FALSE;    STARTUPINFO si = { 0 };    PROCESS_INFORMATION pi = { 0 };    CONTEXT oldContext = { 0 };    CONTEXT newContext = { 0 };    INJECT_CODE ic = { 0 };    DWORD dwOldEip = 0;    si.wShowWindow = SW_SHOWDEFAULT;    si.cb = sizeof(PROCESS_INFORMATION);    HANDLE hThread = NULL;    //以挂起的方式创建进程    bRet = CreateProcess(m_strExePath.GetBuffer(0), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,        NULL, NULL, &si, &pi);    if (!bRet)    {        MessageBox("CreateProcess 失败");        return;    }    g_hProcess1 = pi.hProcess;    hThread = pi.hThread;    //申请内存    g_lpBuffer1 = VirtualAllocEx(g_hProcess1, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    if (g_lpBuffer1 == NULL)    {        MessageBox("VirtualAllocEx 失败");        return;    }    //给ShellCode结构体赋值    ic.byPUSH = 0x68;    ic.dwPUSH_VALUE = 0x12345678;    ic.byPUSHFD = 0x9C;    ic.byPUSHAD = 0x60;    ic.byMOV_EAX = 0xB8;    ic.dwMOV_EAX_VALUE = (DWORD)g_lpBuffer1 + offsetof(INJECT_CODE, szDllPath);    ic.byPUSH_EAX = 0x50;    ic.byMOV_ECX = 0xB9;    ic.dwMOV_ECX_VALUE = (DWORD)&LoadLibrary;    ic.wCALL_ECX = 0xD1FF;    ic.byPOPAD = 0x61;    ic.byPOPFD = 0x9D;    ic.byRETN = 0xC3;    memcpy(ic.szDllPath, m_strDllPath.GetBuffer(0), m_strDllPath.GetLength());    //写入ShellCode    bRet = WriteProcessMemory(g_hProcess1, g_lpBuffer1, &ic, sizeof(ic), NULL);    if (!bRet)    {        MessageBox("写入内存失败");        return;    }    //获取线程上下文    oldContext.ContextFlags = CONTEXT_FULL;    bRet = GetThreadContext(hThread, &oldContext);    if (!bRet)    {        MessageBox("GetThreadContext 失败");        return;    }    newContext = oldContext;#ifdef _WIN64    newContext.Rip = (DWORD)g_lpBuffer1;    dwOldEip = newContext.Rip;#else     newContext.Eip = (DWORD)g_lpBuffer1;    dwOldEip = newContext.Eip;#endif    //;将指针指向ShellCode第一句push 12345678h中的地址,写入返回地址    bRet = WriteProcessMemory(g_hProcess1, ((char*)g_lpBuffer1) + 1, &dwOldEip, sizeof(DWORD), NULL);    if (!bRet)    {        MessageBox("写入内存失败");        return;    }    bRet = SetThreadContext(hThread, &newContext);    if (!bRet)    {        MessageBox("SetThreadContext 失败");        return;    }    //然后把主线程跑起来    bRet = ResumeThread(hThread);    if (bRet == -1)    {        MessageBox("ResumeThread 失败");        return;    }}void ProcessInject::OnBnClickedFreemem(){    // TODO:  在此添加控件通知处理程序代码    if (!VirtualFreeEx(g_hProcess1, g_lpBuffer1, 0, MEM_RELEASE))    {        MessageBox("VirtualFreeEx 失败");        return;    }    MessageBox("释放对方空间成功");}void ProcessInject::OnBnClickedButton3(){    // TODO:  在此添加控件通知处理程序代码    char szFilter[] = "可执行程序|*.exe";    CFileDialog fileDlg(TRUE, "exe", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);    UpdateData(TRUE);    if (fileDlg.DoModal() == IDOK)    {        m_strExePath = fileDlg.GetPathName();    }    UpdateData(FALSE);}void ProcessInject::OnBnClickedButton4(){    // TODO:  在此添加控件通知处理程序代码    char szFilter[] = "动态链接库|*.dll";    CFileDialog fileDlg(TRUE, "dll", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);    UpdateData(TRUE);    if (fileDlg.DoModal() == IDOK)    {        m_strDllPath = fileDlg.GetPathName();    }    UpdateData(FALSE);}

转载于:https://blog.51cto.com/haidragon/2306923

你可能感兴趣的文章
virtualbox+vagrant学习-4-Vagrantfile-5-Machine Settings
查看>>
Example of DenseCRF with non-RGB data
查看>>
C++ sort
查看>>
php中Redis配置小解
查看>>
cocos 自适应屏幕分辨率
查看>>
人月神话读后感(二)
查看>>
实验一 Java开发环境的熟悉
查看>>
(转) Oracle SQL优化必要的全表扫描思路分析
查看>>
iphone-common-codes-ccteam源代码 CCCommon.m
查看>>
What does the flowchart look like in top Journals?
查看>>
转:OAuth 2.0 介绍
查看>>
C#:解决WCF中服务引用 自动生成代码不全的问题。
查看>>
修改系统和MySQL时区
查看>>
数组的处理方法,filter的用法
查看>>
Python 集合方法总结
查看>>
Python的语言特性
查看>>
codeigniter 中使用 phpexcel
查看>>
JVM监控和调优常用命令工具总结
查看>>
机器学习实战-边学边读python代码(5)
查看>>
对forEach、for-in还有es6的for-of的一些整理
查看>>