zoukankan      html  css  js  c++  java
  • 直接读取修改exe文件

    1、 前言

    配置器的编写有很多的方式,主要是直接修改原始的受控端的程序,有的方式是把受控端和配置信息都放到控制端程序的内部,在需要配置受控端的时候直接输入配置信息,生成受控端;也有的方式是在外部直接修改未配置信息的受控端程序。

    2、编程思路

    • 服务端设置变量,然后读取变量的值。

    • 配置端读取服务端的PE文件,找到变量初始值清空写入新设置的值。

    3、实践代码

    • 服务端

    声明三个已经初始化值的变量

    // URL配置器.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "stdafx.h"  
    
    int main(int argc, char* argv[])
    {
    	TCHAR szIpAddress[] = L"AAAAAAAAAAAAAAAAAAAAAAAAAAAA";                                 // IP地址
    	TCHAR szPort[] = L"BBBBBBBBBBBBBBBBBBBBBBBBBBBB";                                      // 端口号
    	TCHAR szOtherInfo[] = L"CCCCCCCCCCCCCCCCCCCCCCCCCCCC";                                 // 其他信息
    
    	printf("IP:%ls
    Port:%ls
    Other Information:%ls
    ", szIpAddress, szPort, szOtherInfo); // 打印信息
    
    	getchar();
    
    	return 0;
    }
    

    通过010editor编辑器可以看到变量在字符串里的位置,在PE文件里的存储形式如下图。

    因为存放的IP信息,端口信息以及其他信息是存在固定位数的,这个固定的位数也就是AAAAAA....,BBBBB....,CCCCCC三个数组字符串的固定长度。

    生成配置端就是要用同等的数据替换掉原先的信息。

    • 配置器

    三个编辑框分别对应着IP地址、端口号、其他信息。变量名分别为m_szIpStr、m_szPortStr、m_szOtherStr。

    MFC回车会关闭掉程序,需要重写一下PreTranslateMessage虚函数。

    BOOL CMFC配置端Dlg::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
    	{
    		if (GetFocus()->GetDlgCtrlID() == IDC_szIP)//按下回车,如果当前焦点是在自己期望的控件上
    		{
    			// 你想做的事,如果按下回车时焦点在你想要的控件上
    			OnBnChangePE();
    		}
    		return TRUE;
    	}
    	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
    		return TRUE;
    	return CDialogEx::PreTranslateMessage(pMsg);
    }
    
    

    按钮对应的事件函数名是OnBnChangePE();

    UpdateData(true); 是读取数据,False是更新数据。

    
    void CMFC配置端Dlg::OnBnChangePE()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	UpdateData(true);
    
    	BOOL bRet = false;     // 打开状态标志
    	TCHAR * pFileData;     // 文件流内容
    	DWORD d_FileSize;      // 文件大小
    	TCHAR chPath[MAX_PATH];  // 配置文件路径
    
    
    	// 打开要修改的PE文件
    	CFileDialog dlg(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("可执行文件|*.exe||"), this);
    	dlg.m_ofn.lpstrTitle = L"打开URL配置器.exe";
    	if (dlg.DoModal() == IDOK)
    	{
    		CString szPE_Path;
    		szPE_Path = dlg.GetPathName();
    		wmemset(chPath, 0, szPE_Path.GetLength() + 1);
    		wmemcpy(chPath, szPE_Path, szPE_Path.GetLength()+1);
    	}
    	else
    	{
    		return;
    	}
    
    
    	// 读出文件内容并写入  
    	HANDLE hFile = CreateFile(chPath, GENERIC_READ, 0, NULL, OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL, NULL);
    
    	d_FileSize = GetFileSize(hFile, NULL);
    	pFileData = new TCHAR[d_FileSize + 1];
    
    	bRet = ReadFile(hFile, pFileData, d_FileSize, &d_FileSize, NULL);
    	if (0 == bRet)
    	{
    		return;
    	}
    
    	// 替换目标可执行文件中的指定信息:IP port 以及其他的信息  
    	TCHAR szIpStr[] =    L"AAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    	TCHAR szPortStr[] =  L"BBBBBBBBBBBBBBBBBBBBBBBBBBBB";
    	TCHAR szOtherStr[] = L"CCCCCCCCCCCCCCCCCCCCCCCCCCCC";
    
    	TCHAR * pDst;
    	int i = 0;
    
    	// 处理IP字符串  
    	while (true)
    	{
    		if (wcscmp(szIpStr, pFileData + i) == 0)
    		{
    			break;
    		}
    		else
    		{
    			i++;
    		}
    	}
    
    	// 找到IP地址字符串对应的地址偏移
    	pDst = pFileData + i;
    
    	//CString转char 将原先的AAAAA...替换成现在我们要设定的IP地址
    	wmemset(pDst, 0, wcslen(szIpStr)+1);                       // 清空原先AAAA字符串
    	wmemcpy(pDst, m_szIpStr, m_szIpStr.GetLength() + 1);       // 把设定的IP字符串复制到内存中
    
    	// 处理端口字符串  
    	while (true)
    	{
    		if (wcscmp(szPortStr, pFileData + i) == 0)
    		{
    			break;
    		}
    		else
    		{
    			i++;
    		}
    	}
    	pDst = pFileData + i;
    	//CString转char 将原先的BBBBB...替换成现在我们要设定的IP地址
    	wmemset(pDst, 0, wcslen(szPortStr) + 1);                       // 清空原先BBBB字符串
    	wmemcpy(pDst, m_szPortStr, m_szPortStr.GetLength() + 1);       // 把设定的端口字符串复制到内存中
    
    	// 处理其他信息字符串
    	while (true)
    	{
    		if (wcscmp(szOtherStr, pFileData + i) == 0)
    		{
    			break;
    		}
    		else
    		{
    			i++;
    		}
    	}
    	pDst = pFileData + i;
    	//CString转char 将原先的BBBBB...替换成现在我们要设定的IP地址
    	wmemset(pDst, 0, wcslen(szOtherStr) + 1);                      // 清空原先CCCCC字符串
    	wmemcpy(pDst, m_szOtherStr, m_szOtherStr.GetLength() + 1);     // 把设定的端口字符串复制到内存中
    
    	CloseHandle(hFile);                                            //关闭句柄
    
    
    
    	//////////////////////////////////
    	// 保存文件内容到新的exe文件中 /// 
    	//////////////////////////////////
    
    
    	// 保存新PE文件路径
    	CFileDialog dlg_NewSavePath(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("可执行文件|*.exe||"), this);
    	dlg_NewSavePath.m_ofn.lpstrTitle = L"保存的路径.exe";
    	if (dlg_NewSavePath.DoModal() == IDOK)
    	{
    		CString szPE_Path;
    		szPE_Path = dlg_NewSavePath.GetPathName();
    		wmemset(chPath, 0, szPE_Path.GetLength() + 1);               
    		wmemcpy(chPath, szPE_Path, szPE_Path.GetLength() + 1);
    	}
    	else
    	{
    		return;
    	}
    
    	// 新建文件
    	hFile = CreateFile(chPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
    		FILE_ATTRIBUTE_NORMAL, NULL);
    	
    	// 写入文件
    	bRet = WriteFile(hFile, pFileData, d_FileSize, &d_FileSize, NULL);
    	if (bRet == 0)
    	{
    		return;
    	}
    	// 关闭句柄
    	CloseHandle(hFile);
    }
    

    3、修改后的效果对比

    4、参考

    通过直接读取修改exe文件的方式编写远控/木马配置器

    http://blog.csdn.net/junbopengpeng/article/details/37915133

  • 相关阅读:
    【File类:重命名功能】
    一段代码-Java
    Galahad
    简单的中位数
    小A的题 线段树区间赋值
    上升子序列方案数
    Superdoku 二分图匹配
    Haybale Guessing 区间并查集
    Dijkstra+二分查找
    莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/17bdw/p/8479320.html
Copyright © 2011-2022 走看看