EXE加锁器 只是思路
代码有点乱 但是我不想整理
// AddBoxDlg.cpp : 实现文件
// #include "stdafx.h"
#include "AddBox.h"
#include "AddBoxDlg.h"
#include "afxdialogex.h"
#include "PEInfo.h"
#include <ImageHlp.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_SECDATA_SIZE 2048
#pragma comment (lib,"Dbghelp.lib") // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 char szTargetPath[MAX_PATH] = "D:\\Target.exe"; //目标文件的路径
char szPatchPath[MAX_PATH] = "D:\\helloworld_1.exe"; //补丁文件的路径
char szModifyPEPath[MAX_PATH] = "D:\\haha.exe"; //修改后生成新文件的路径 class CAboutDlg : public CDialogEx
{
public:
CAboutDlg(); // 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现
protected:
DECLARE_MESSAGE_MAP()
}; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
} void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP() // CAddBoxDlg 对话框 CAddBoxDlg::CAddBoxDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_ADDBOX_DIALOG, pParent)
, m_strPEFilePath(_T(""))
, m_strBoxTitle(_T(""))
, m_strBoxContent(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CAddBoxDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_strPEFilePath);
DDX_Text(pDX, IDC_EDIT2, m_strBoxTitle);
DDX_Text(pDX, IDC_EDIT3, m_strBoxContent);
} BEGIN_MESSAGE_MAP(CAddBoxDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_SCAN, &CAddBoxDlg::OnBnClickedButtonScan)
ON_BN_CLICKED(IDOK, &CAddBoxDlg::OnBnClickedOk)
END_MESSAGE_MAP() // CAddBoxDlg 消息处理程序 BOOL CAddBoxDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} void CAddBoxDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
} // 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。 void CAddBoxDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
} //当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CAddBoxDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
} void CAddBoxDlg::OnBnClickedButtonScan()
{
// TODO: 在此添加控件通知处理程序代码
static const TCHAR* szFileFilter = TEXT("PE File(*.exe)|*.exe||");
CFileDialog filedlg(TRUE, , , | , szFileFilter);
if (IDOK == filedlg.DoModal())
{
m_strPEFilePath = filedlg.GetPathName();
this->UpdateData(FALSE);
}
} void CAddBoxDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
//验证用户输入的合法性
//if (m_strPEFilePath.IsEmpty())
//{
// MessageBox(TEXT("请选择目标PE文件路径"));
// return;
//} //if (m_strBoxTitle.IsEmpty())
//{
// MessageBox(TEXT("请输入目标PE弹出对话框标题"));
// return;
//} //if (m_strBoxContent.IsEmpty())
//{
// MessageBox(TEXT("请输入目标PE弹出对话框内容"));
// return;
//} ////加载并链接到用户所选择PE文件的映像
//FILEMAPITEM OldFileMap = { 0 }, NewFileMap = { 0 };
//if (!PEInfo.CreateFileMap(m_strPEFilePath.GetBuffer(0), &OldFileMap))
//{
// MessageBox(TEXT("创建目标PE文件映像失败!"));
// return;
//} ////将OldFileMap基本信息保存到PEInfo中
//PEInfo.GetBaseInfo(&OldFileMap); ////初始化新区块头
//PEInfo.InitNewSectionHeader(); //TCHAR szNewFilePathName[MAX_PATH] = { 0 };
//BYTE pSectionData[MAX_SECDATA_SIZE] = { 0 }; ////生成新区块数据并修正新区块头
//DWORD dwSecDataSize = GenSecData(pSectionData, OldFileMap.ImageBase);
//if (dwSecDataSize > PEInfo.NewSectionHeader.SizeOfRawData)
//{
// PEInfo.NewSectionHeader.SizeOfRawData = dwSecDataSize;
// PEInfo.AdjustSectionSize();
//} ////得到要建立的PE_Box.exe路径
//CString strTempPath = m_strPEFilePath;
//strTempPath.SetAt(strTempPath.GetLength() - 4, 0);
//wsprintf(szNewFilePathName, TEXT("%s%s"), strTempPath, TEXT("_box.exe")); ////创建一个新的映像
//DWORD dwNewFileSize = PEInfo.NewSectionHeader.PointerToRawData + PEInfo.NewSectionHeader.SizeOfRawData;
//if (!PEInfo.CreateNewFileMap(szNewFilePathName, dwNewFileSize, &NewFileMap))
//{
// MessageBox(TEXT("创建新的映像文件失败!"));
// DeleteFile(szNewFilePathName);
// return;
//} ////拷贝原PE数据
//memcpy(NewFileMap.ImageBase, OldFileMap.ImageBase, this->PEInfo.NewSectionHeader.PointerToRawData);
////将及新区块头拷贝到新文件映像
//PEInfo.AddNewSectionHeader(&OldFileMap, &NewFileMap, dwNewFileSize);
////将新区块内容拷贝到新文件映像
//LPVOID pvNewSec = (LPVOID)((DWORD)(NewFileMap.ImageBase) + PEInfo.NewSectionHeader.PointerToRawData);
//memcpy(pvNewSec, pSectionData, this->PEInfo.NewSectionHeader.SizeOfRawData); //PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)NewFileMap.ImageBase;
//PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)NewFileMap.ImageBase + pDosHeader->e_lfanew);
//PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)(&pNtHeader->OptionalHeader); ////修改输入表大小和位置
//pOptionalHeader->DataDirectory[1].Size += 0x14;
//pOptionalHeader->DataDirectory[1].VirtualAddress = PEInfo.NewSectionHeader.VirtualAddress; ////清除绑定输入表
//pOptionalHeader->DataDirectory[11].Size = 0;
//pOptionalHeader->DataDirectory[11].VirtualAddress = 0; ////修改程序入口
//pOptionalHeader->AddressOfEntryPoint = PEInfo.NewSectionHeader.VirtualAddress + this->dwNewEntryOff; ////刷新映像缓冲 并卸载两个文件映像
//FlushViewOfFile(NewFileMap.ImageBase, dwNewFileSize);
//PEInfo.DeleteMap(&OldFileMap);
//PEInfo.DeleteMap(&NewFileMap); //MessageBox(TEXT("添加PE _Box成功! 请到目标PE文件所在路径查看")); PVOID lpPatchMemory = NULL;
PVOID lpTargetMemory = NULL;
ULONG ulPatchSize = ;
ULONG ulTargetSize = ; lpTargetMemory = GetFileBaseAddressAndSize(szTargetPath, &ulTargetSize);
lpPatchMemory = GetFileBaseAddressAndSize(szPatchPath, &ulPatchSize); //patch 补丁 InsertPatchFileToTargetFile(lpTargetMemory, lpPatchMemory, ulTargetSize); CDialogEx::OnOK();
} BOOL CAddBoxDlg::InsertPatchFileToTargetFile(PVOID lpTargetMemory, PVOID lpPatchMemory, ULONG ulTargetSize)
{
DWORD dwFileAlignPatchCodeSize = ;
DWORD dwRealPatchCodeSize = ;
ULONG ulPathCodeSectionRVA = ;
ULONG ULNewFileOEP = ;
ULONG ulOldOEP = ;
ULONG ulFileAlignment = ; dwRealPatchCodeSize = GetFileInfo(lpPatchMemory, RealSectionSize); //获得Patch文件未对齐时的大小
ulPathCodeSectionRVA = GetFileInfo(lpPatchMemory, SectionRVA); //获得Patch文件所要加载节的RVA
ulOldOEP = GetFileInfo(lpTargetMemory, AddressOfEntryPoint);
ulFileAlignment = GetFileInfo(lpTargetMemory, FileAlignment);
ULNewFileOEP = GetNewFileOEP(lpTargetMemory);
dwFileAlignPatchCodeSize = Align(dwRealPatchCodeSize, ulFileAlignment); //align 对齐 返回需要申请的个数 PVOID NewFileBaseAddress = malloc(ulTargetSize + dwFileAlignPatchCodeSize);
memset(NewFileBaseAddress, , ulTargetSize + dwFileAlignPatchCodeSize); memcpy(NewFileBaseAddress, lpTargetMemory, ulTargetSize);
memcpy((PVOID)((ULONG_PTR)NewFileBaseAddress + ulTargetSize), (PVOID)((ULONG_PTR)lpPatchMemory + ulPathCodeSectionRVA), dwRealPatchCodeSize); ModifyPatchCodeJumpAddress(NewFileBaseAddress, ulTargetSize + dwRealPatchCodeSize, ULNewFileOEP, ulOldOEP, dwRealPatchCodeSize); //修改PatchCode结尾E9跳转地址 ModifyParameter(NewFileBaseAddress, ulTargetSize, dwFileAlignPatchCodeSize, dwRealPatchCodeSize, ULNewFileOEP); //修改最后一节和PE头的参数 HANDLE hNewFile = CreateFileA(szModifyPEPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (hNewFile == INVALID_HANDLE_VALUE)
{
printf("CreateFileA Failed!\r\n");
return FALSE;
}
DWORD dwRet = ;
if (WriteFile(hNewFile, NewFileBaseAddress, ulTargetSize + dwFileAlignPatchCodeSize, &dwRet, NULL) == )
{
printf("WriteFile Failed!\r\n");
return FALSE;
}
else
{
printf("Succeed!\r\n");
} return TRUE; }
VOID CAddBoxDlg::ModifyParameter(PVOID FileBaseAddress, ULONG ulTargetSize, ULONG ulFlieAlignPatchCodeSize, ULONG ulRealPatchCodeSize, ULONG ulNewOEP)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); ULONG MemoryAlignment = NTHead->OptionalHeader.SectionAlignment;
ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections; SectionHead[ulNumberOfSection - ].Characteristics = 0x60000020;
SectionHead[ulNumberOfSection - ].Misc.VirtualSize = SectionHead[ulNumberOfSection - ].SizeOfRawData + ulRealPatchCodeSize;
SectionHead[ulNumberOfSection - ].SizeOfRawData += ulFlieAlignPatchCodeSize; NTHead->OptionalHeader.SizeOfImage = Align(SectionHead[ulNumberOfSection - ].VirtualAddress + SectionHead[ulNumberOfSection - ].SizeOfRawData, MemoryAlignment);
NTHead->OptionalHeader.AddressOfEntryPoint = ulNewOEP;
} VOID CAddBoxDlg::ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress, ULONG NewFileSize, ULONG ULNewFileOEP, ULONG ulOldOEP, ULONG ulRealPatchCodeSize)
{
UCHAR JmpCode[] = "\x00\x00\x00\x00";
*(int*)JmpCode = (ulOldOEP + ) - (ULNewFileOEP + ulRealPatchCodeSize); //+1越过E9
memcpy((PVOID)((UCHAR*)lpNewFileBaseAddress + NewFileSize - ), JmpCode, strlen((char*)JmpCode)); //看内存 E9后有5个非0字节,所以不是-4 } ULONG CAddBoxDlg::Align(ULONG FileSize, ULONG ulAlignment)
{
if (FileSize%ulAlignment != )
{
int Temp = FileSize / ulAlignment;
return ulAlignment*(Temp + );
}
else
{
return FileSize;
}
} ULONG CAddBoxDlg::GetNewFileOEP(PVOID lpTargetMemory)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)lpTargetMemory;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections;
ULONG ulNewFileOEP = SectionHead[ulNumberOfSection - ].VirtualAddress +
SectionHead[ulNumberOfSection - ].SizeOfRawData;
return ulNewFileOEP;
}
DWORD CAddBoxDlg::GetFileInfo(PVOID FileBaseAddress, PATCH_FILE_INFO Type)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead + DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead + sizeof(IMAGE_NT_HEADERS)); DWORD dwEntryPoint = NTHead->OptionalHeader.AddressOfEntryPoint;
DWORD dwRet = ;
if (Type == AddressOfEntryPoint)
{
dwRet = dwEntryPoint;
}
if (Type == FileAlignment)
{
dwRet = NTHead->OptionalHeader.FileAlignment;
} for (int i = ;i<NTHead->FileHeader.NumberOfSections;i++)
{
if (dwEntryPoint >= SectionHead[i].VirtualAddress && dwEntryPoint<SectionHead[i].VirtualAddress + SectionHead[i].SizeOfRawData)
{ if (Type == RealSectionSize)
{
dwRet = SectionHead[i].Misc.VirtualSize;
}
if (Type == SectionRVA)
{
dwRet = SectionHead[i].PointerToRawData;
} } } if (dwRet == NULL)
{
printf("GetFileInfo Failed!\r\n");
} return dwRet; }
PVOID CAddBoxDlg:: GetFileBaseAddressAndSize(char* szFilePath, PULONG ulFileSize)
{
HANDLE hFile = CreateFileA(szFilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
int a = GetLastError();
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile Failed!\r\n");
return NULL;
}
*ulFileSize = GetFileSize(hFile, NULL); if (!(*ulFileSize))
{
printf("GetFileSize Failed!\r\n");
CloseHandle(hFile);
return NULL;
}
HANDLE hMapFile = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
,
,
NULL); if (hMapFile == INVALID_HANDLE_VALUE)
{
printf("CreateFileMapping Failed!\r\n");
CloseHandle(hFile);
return NULL;
} PVOID FileBaseAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL);
if (FileBaseAddress == NULL)
{
CloseHandle(hFile);
CloseHandle(hMapFile);
printf("MapViewOfFile Failed!\r\n");
return NULL;
} return FileBaseAddress;
} DWORD CAddBoxDlg::GenSecData(PBYTE pData, LPVOID ImageBase)
{
//相关首部
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)ImageBase + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader; //得到输入表数据
PIMAGE_DATA_DIRECTORY pImportData = (PIMAGE_DATA_DIRECTORY)(&(pOptionalHeader->DataDirectory[]));
PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pNtHeader,
ImageBase, pImportData->VirtualAddress, NULL); //统计IID数量 用于后面添加新的IID
this->dwIIDNum = ;
while (pIID[this->dwIIDNum].FirstThunk)
{
this->dwIIDNum++;
} const char szDllName[] = "USER32.dll";
const char szFunName[] = "MessageBoxA"; //计算各项数据的摆放偏移
this->dwDllNameOff = pImportData->Size + 0x14;
this->dwFunNameOff = this->dwDllNameOff + sizeof(szDllName) + 0x3;
this->dwIATOff = this->dwFunNameOff + sizeof(szFunName) + 0x4;
this->dwBoxTitleOff = this->dwIATOff + ;
char pTitle[] = { };
char pContent[] = { };
GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT2, pTitle, );
GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT3, pContent, );
this->dwBoxContentOff = this->dwBoxTitleOff + strlen(pTitle) + ;
this->dwNewEntryOff = this->dwBoxContentOff + strlen(pContent) + ; //写入数据
//拷贝输入表数据
memcpy(pData, (LPVOID)pIID, pImportData->Size); //写入新输入表条目数据
//这里新IID的起始地址用dwIIDNum*0x14计算 而不用DataDirectory[1].size(可能有对齐问题,前者偏移140 后者160)
PIMAGE_IMPORT_DESCRIPTOR pNewIID = PIMAGE_IMPORT_DESCRIPTOR(pData + this->dwIIDNum * 0x14);
pNewIID->FirstThunk = this->dwIATOff + this->PEInfo.NewSectionHeader.PointerToRawData;
pNewIID->OriginalFirstThunk = pNewIID->FirstThunk;
pNewIID->ForwarderChain = 0xFFFFFFFF;
pNewIID->TimeDateStamp = 0xFFFFFFFF;
pNewIID->Name = this->PEInfo.NewSectionHeader.PointerToRawData + this->dwDllNameOff;
//将IAT指向函数名
*((DWORD*)(pData + this->dwIATOff))
= this->PEInfo.NewSectionHeader.VirtualAddress + this->dwFunNameOff;
//写入字符串数据
memcpy(pData + this->dwDllNameOff, szDllName, sizeof(szDllName)); //DllName
memcpy(pData + this->dwFunNameOff + , szFunName, sizeof(szFunName)); //FunName(前面留两个字节作序号)
memcpy(pData + this->dwBoxTitleOff, pTitle, strlen(pTitle) + ); //BoxTitle
memcpy(pData + this->dwBoxContentOff, pContent, strlen(pContent) + ); //BoxContent //代码数据(程序入口)
/**********************************
/ pushad
/ push 0
/ push 0x11111111 //指向消息框标题 需修正
/ push 0x11111111 //指向消息框内容 需修正
/ push 0
/ call dword ptr MessageBoxA
/ popad
/ jmp 0x11111111 //指向原始入口 需修正
*/
//写入入口代码
BYTE pbCode[] = { 0x60, 0x6A, 0x00, 0x68, 0x11, 0x11, 0x11, 0x11,
0x68, 0x11, 0x11, 0x11, 0x11, 0x6A, 0x00, 0xFF, 0x15, 0xBC, 0xF2, 0x42,
0x00, 0x61, 0xE9, 0x11, 0x11, 0x11, 0x11 }; memcpy(pData + this->dwNewEntryOff, pbCode, sizeof(pbCode)); //计算JMP跳转值
DWORD dwOldEntryRVA = pOptionalHeader->AddressOfEntryPoint;
DWORD dwNewEntryRVA = this->PEInfo.NewSectionHeader.VirtualAddress + this->dwNewEntryOff + ;
DWORD dwJmpDist = dwOldEntryRVA - dwNewEntryRVA - ; //修正代码块中三个0x11111111待修改操作数
//修正BoxTitle VA
*((DWORD*)(pData + this->dwNewEntryOff + )) = pOptionalHeader->ImageBase + \
this->PEInfo.NewSectionHeader.VirtualAddress + this->dwBoxTitleOff;
//修正BoxContent VA
*((DWORD*)(pData + this->dwNewEntryOff + )) = pOptionalHeader->ImageBase + \
this->PEInfo.NewSectionHeader.VirtualAddress + this->dwBoxContentOff;
//修正IAT VA(call ****)
*((DWORD*)(pData + this->dwNewEntryOff + )) = pOptionalHeader->ImageBase + \
this->PEInfo.NewSectionHeader.VirtualAddress + this->dwIATOff;
//修正jmp操作数
*((DWORD*)(pData + this->dwNewEntryOff + )) = dwJmpDist; return this->dwNewEntryOff + sizeof(pbCode) + 0x10;
}
EXE加锁器 只是思路的更多相关文章
- EXE捆绑器
释放的方法真没想到 太神奇了 // 文件捆绑器Dlg.cpp : 实现文件 // #include "stdafx.h" #include "文件捆绑器.h" ...
- 用urllib2实现一个下载器的思路
下载器的构造 用urllib2实现下载器时从以下几个层面实现功能和灵活性: handler redirect, cookie, proxy 动作 timeout 构造请求 headers: ua, c ...
- STL空间配置器
1.什么是空间配置器? 空间配置器负责空间配置与管理.配置器是一个实现了动态空间配置.空间管理.空间释放的class template.以内存池方式实现小块内存管理分配.关于内存池概念可以点击:内存池 ...
- 编译:ffmpeg,精简ffmpeg.exe
网上下载的各种 ffmpeg.exe ,最少都有11M+ 而我只需要处理 mp4 和 mp3,在网上搜索了一下精简ffmpeg的文章,折腾一天,也没有完全搞定,但多少有些收获,记录一下: 从 www. ...
- 强行替换exe图标的方法
说句实话,要想用普通的方法来替换图标,不是完全不可行,当然也不是完全可行.这个看似简单的问题并不是想象中那么容易解决,为什么有人修改exe的图标总是失败,其实他忽视了exe和图标的复杂性,用简单的方法 ...
- 编程之美之数独求解器的C++实现方法
编程之美的第一章的第15节.讲的是构造数独.一開始拿到这个问题的确没有思路, 只是看了书中的介绍之后, 发现原来这个的求解思路和N皇后问题是一致的. 可是不知道为啥,反正一開始确实没有想到这个回溯法. ...
- Python入门之函数的装饰器
本章目录: 装饰器: 一.为什么要用装饰器 二.什么是装饰器 三.无参装饰器 四.装饰器语法糖 五.认证装饰器实现 六.叠加多个装饰器 七.带参装饰器 ======================== ...
- 基于Spring和Mybatis拦截器实现数据库操作读写分离
首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...
- windows资源管理器(只能看,不能用)
实现Windows资源管理器 问题描述 Windows资源管理器是用来管理计算机资源的窗口,电脑里所有的文件都可以在资源管理器里找到,可以在资源管理器里查看文件夹的分层结构,可以利用资源管理器快速进行 ...
随机推荐
- Jenkins安装与基本配置
环境:centos 6.5,jenkins依赖jdk,当前版本推荐jdk1.8,1.7也可以用 首先,机器应该可以访问外网,用yum安装即可(这里版本号是2.19.4): wget -O /etc/y ...
- python 学习笔记十九 django深入学习四 cookie,session
缓存 一个动态网站的基本权衡点就是,它是动态的. 每次用户请求一个页面,Web服务器将进行所有涵盖数据库查询到模版渲染到业务逻辑的请求,用来创建浏览者需要的页面.当程序访问量大时,耗时必然会更加明显, ...
- Allegro 导入DXF文件,保留布好的线路信息
最近智能钥匙产品开发过程中,由于结构装配尺寸的偏差,需要对电路PCB外框OUTLINE进行缩小调整,并且USB插座定位孔改变. Allegro软件在线性绘制方面是有严重缺陷的,想绘制一个异形的板框比较 ...
- 工厂食堂3D指纹考勤系统解决方案
指纹考勤就餐管理系统利用3D活体指纹技术完成对正式员工就餐管理.就餐者只需办理完入职手续,并登记考勤指纹,就可通过考勤指纹在工厂食堂领餐. 大多数工厂食堂就餐是福利性的,只准员工就餐,不准员工带亲戚朋 ...
- mySQL数据库Sql语句执行效率检查--Explain命令
mysql性能的检查和调优方法 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的 ...
- CSS关于子元素设置了float属性后父元素高度为0的解释和解决方法
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- git备份sublime插件及配置
github备份sublime配置 sublime使用的时间长了,渐渐的就积累了一些有用甚至离不开的插件.但是有时候系统会出点问题,或者换电脑什么的,这时候要想在找回那个曾经的sublime就不那么容 ...
- Deep Learning 19_深度学习UFLDL教程:Convolutional Neural Network_Exercise(斯坦福大学深度学习教程)
理论知识:Optimization: Stochastic Gradient Descent和Convolutional Neural Network CNN卷积神经网络推导和实现.Deep lear ...
- Spring集成Hibernate映射文件的4种方式
概要: 在Spring的applicationContext.xml中集成Hibernate映射文件,通常是在<sessionFactory>这个Bean实例中进行的,若配置的映射文件较少 ...
- 6.1-CALayer 使用
@设置圆角 注意点 1圆角效果,并不是在给定frame布局后有,要给定内容后才有 //头像 NSData *data = [[DJXMPPTool sharedInstance].cardAvatar ...