c ++内存将字节写入地址 Windows 内核驱动程序
c++ memory write bytes to address with Windows kernel driver
所以我会解释我想做什么,我想知道为什么它对我不起作用,
我从 CE 找到了一个地址:它是:0x04013118
,其值是一个字节数组:DC 04 00 00 04 02 00 00
我想做的是用内核驱动程序将内存写入这个地址一个新值,它也是一个字节数组:
DC 04 00 00 00 00 00 00
这是我尝试使用的大部分功能,但大部分参数都在其他 类 中定义,我无法提供所有这些,但我认为部分代码(只是我要放在这里) 已经够了,
这是 MemoryManager.cpp 的一部分,也是 BypassMemory.cpp:
void MemoryManager::readMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize){
if(!allIsWell)
return;
struct{
HANDLE ProcessHandle;
PVOID BaseAddress;
PVOID Buffer;
SIZE_T BufferSize;
PSIZE_T NumberOfBytesRead;
} input = { processHandle, BaseAddress, Buffer, BufferSize, NumberOfBytes };
IO_STATUS_BLOCK ioStatusBlock;
NtDeviceIoControlFile(m_hDriver, nullptr, nullptr, nullptr, &ioStatusBlock, MM_READVIRTUALMEMORY, &input, sizeof(input), nullptr, 0);
}
void MemoryManager::writeMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize) {
if (!allIsWell)
return;
struct {
HANDLE ProcessHandle;
PVOID BaseAddress;
PVOID Buffer;
SIZE_T BufferSize;
PSIZE_T NumberOfBytesWritten;
} input = { processHandle, BaseAddress, Buffer, BufferSize, NumberOfBytesWrite };
IO_STATUS_BLOCK ioStatusBlock;
NtDeviceIoControlFile(m_hDriver, nullptr, nullptr, nullptr, &ioStatusBlock, MM_WRITEVIRTUALMEMORY, &input, sizeof(input), nullptr, 0);
}
bool MemoryManager::search(BYTE * bSearchData, int nSearchSize, DWORD_PTR dwStartAddr, DWORD_PTR dwEndAddr, BOOL bIsCurrProcess, int iSearchMode, std::vector<DWORD_PTR> &vRet){
MEMORY_BASIC_INFORMATION mbi;
std::vector<MEMORY_REGION> m_vMemoryRegion;
mbi.RegionSize = 0x400;
DWORD dwAddress = dwStartAddr;
MEMORY_REGION memSectorList[1000];
int memSectorIndex = 0;
while(VirtualQueryEx(processHandle, (LPCVOID)dwAddress, &mbi, sizeof(mbi)) && (dwAddress < dwEndAddr) && ((dwAddress + mbi.RegionSize) > dwAddress)){
if(
(mbi.State == MEM_COMMIT) &&
((mbi.Protect & PAGE_GUARD) == 0) &&
(mbi.Protect != PAGE_NOACCESS) &&
((mbi.AllocationProtect & PAGE_NOCACHE) != PAGE_NOCACHE)
){
MEMORY_REGION mData = { 0 };
mData.dwBaseAddr = (DWORD_PTR)mbi.BaseAddress;
mData.dwMemorySize = mbi.RegionSize;
m_vMemoryRegion.push_back(mData);
memSectorList[memSectorIndex] = mData;
memSectorIndex++;
}
dwAddress = (DWORD)mbi.BaseAddress + mbi.RegionSize;
}
std::vector<MEMORY_REGION>::iterator it;
int memSectorCount = memSectorIndex;
memSectorIndex = 0;
DWORD_PTR curAddr = dwStartAddr;
while(curAddr < dwEndAddr){
VirtualQueryEx(processHandle, (LPCVOID)curAddr, &mbi, sizeof(mbi));
long regionSizeOrg = mbi.RegionSize;
long regionSize = mbi.RegionSize;
if(regionSize > 10){
BYTE* pCurrMemoryData = new BYTE[regionSize];
ZeroMemory(pCurrMemoryData, regionSize);
writeMemory((PVOID)curAddr, (PVOID*)pCurrMemoryData, regionSize);
DWORD_PTR dwOffset = 0;
int iOffset = find(pCurrMemoryData, regionSize, bSearchData, nSearchSize);
while(iOffset != -1){
dwOffset += iOffset;
vRet.push_back(dwOffset + curAddr);
dwOffset += nSearchSize;
iOffset = find(pCurrMemoryData + dwOffset, regionSize - dwOffset - nSearchSize, bSearchData, nSearchSize);
}
delete[] pCurrMemoryData;
}
memSectorIndex++;
curAddr = curAddr + (DWORD_PTR)regionSizeOrg;
continue;
}
return TRUE;
}
int MemoryManager::find(BYTE *buffer, int dwBufferSize, BYTE *bstr, DWORD dwStrLen){
if(dwBufferSize < 0){
return -1;
}
DWORD i, j;
for(i = 0; i < dwBufferSize; i++){
for(j = 0; j < dwStrLen; j++){
if(buffer[i + j] != bstr[j] && bstr[j] != '?')
break;
}
if(j == dwStrLen)
return i;
}
return -1;
}
DWORD MemoryManager::dRead(DWORD base){
readMemory((PVOID)base, &_d, 4);
return _d;
}
void MemoryManager::dWrite(DWORD base){
writeMemory((PVOID)base, &_d, 4);
}
/* these are in bypassmemory.cpp */
void BypassMemory::init(){
viewWordBase = getAddr(); // = works and gets Addrs = 0x04013118
if(viewWordBase){
std::cout << "found addr : " << termcolor::green << std::hex << viewWordBase << std::dec << termcolor::reset << "\n";
} else{
std::cout << termcolor::red << "View World Not Found ! \n" << termcolor::reset;
return;
}
// so basiclly my addres = 0x04013118 and value of it = DC 04 00 00 04 02 00 00
BYTE writePattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//const char* writePtr = "DC 04 00 00 00 00 00 00"; // i tried also this but didn't work
MemoryManager->writeMemory((PVOID)bypassAddr1, &writePattern, sizeof(writePattern)); // i write to the base addres ( 0x04013118, new val = DC 04 00 00 00 00 00 00)
//MemoryManager->writeMemory((PVOID)bypassAddr1, &writePtr, sizeof(writePtr));
}
DWORD BypassMemory::getAddr(){
BYTE pattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 };
std::vector<DWORD_PTR> foundedBases;
MemoryManager->search(pattern, sizeof(pattern), 0x04000000, 0x05000000, false, 0, foundedBases);
std::cout << "founded bases size: " << termcolor::green << std::hex << foundedBases.size() << std::dec << termcolor::reset << "\n";
for(int i = 0; i < foundedBases.size(); i++){
DWORD cand = dGet(foundedBases[i]); // this reads inside the address purpose to check
std::cout << "founded bases addr: " << termcolor::green << std::hex << foundedBases[i] << std::dec << termcolor::reset << "\n";
return foundedBases[i];
}
return 0;
}
int main()
{
int Pid = ProcManager::getAowProcID();
pMemoryManager->init(Pid, true);
BypassMemory->init();
return 0;
}
这是MemoryManager.h:(如果有人感兴趣的话)
#define MM_DEVICE_TYPE 0x9999
#define MM_CTL_CODE(x) CTL_CODE(MM_DEVICE_TYPE, 0x800 + x, METHOD_NEITHER, FILE_ANY_ACCESS)
#define MM_READVIRTUALMEMORY MM_CTL_CODE(56)
#define MM_WRITEVIRTUALMEMORY MM_CTL_CODE(57)
typedef struct _MEMORY_REGION{
DWORD_PTR dwBaseAddr;
DWORD_PTR dwMemorySize;
}MEMORY_REGION;
class MemoryManager{
public:
MemoryManager();
~MemoryManager();
HANDLE m_hDriver = nullptr;
HANDLE processHandle;
int processId = 0;
bool allIsWell = false;
PSIZE_T NumberOfBytes = nullptr;
PSIZE_T NumberOfBytesWrite = nullptr; // created by oday
DWORD _d;
float _f;
int _i;
BYTE* _b = new BYTE[1];
int _dw = 1245; // created by oday
void init(int pid, bool debug);
bool connectToDriver(std::string m_strDeviceName);
void readMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize);
void writeMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize); // created by oday
bool search(BYTE * bSearchData, int nSearchSize, DWORD_PTR dwStartAddr, DWORD_PTR dwEndAddr, BOOL bIsCurrProcess, int iSearchMode, std::vector<DWORD_PTR>& vRet);
int find(BYTE * buffer, int dwBufferSize, BYTE * bstr, DWORD dwStrLen);
void dWrite(DWORD base); // created by oday
DWORD dRead(DWORD base);
float fRead(DWORD base);
int iRead(DWORD base);
BYTE* bRead(DWORD base);
};
extern MemoryManager* pMemoryManager;
有趣的地方在于:
BYTE writePattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
pMemoryManager->writeMemory((PVOID)bypassAddr1, &writePattern, sizeof(writePattern));
我从当前模式的搜索功能中成功读取了地址 0x04013118,一切正常,但是当我尝试用我在这里提到的内容写入该地址时
内存中什么也没发生,值也没有改变,有人知道为什么什么都没有发生,内存也没有改变吗?我很确定我的内核驱动程序与此无关,因为它存在漏洞并且具有读写权限。
我会为其他有同样问题的人得出一个简短的结论。
主要问题是作者无法写入进程内存中的特定内存位置。
借助 windows API 函数 VirtualProtectEx
作者能够更改虚拟内存页面访问位以允许写入所需内存地址的内存页面.
程序包括:
- 正在调用
VirtualProtectEx
以启用写入内存页面
- 写入该页面中的特定内存位置
- 再次调用
VirtualProtectEx
重置页面访问位
所以我会解释我想做什么,我想知道为什么它对我不起作用,
我从 CE 找到了一个地址:它是:0x04013118
,其值是一个字节数组:DC 04 00 00 04 02 00 00
我想做的是用内核驱动程序将内存写入这个地址一个新值,它也是一个字节数组:
DC 04 00 00 00 00 00 00
这是我尝试使用的大部分功能,但大部分参数都在其他 类 中定义,我无法提供所有这些,但我认为部分代码(只是我要放在这里) 已经够了,
这是 MemoryManager.cpp 的一部分,也是 BypassMemory.cpp:
void MemoryManager::readMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize){
if(!allIsWell)
return;
struct{
HANDLE ProcessHandle;
PVOID BaseAddress;
PVOID Buffer;
SIZE_T BufferSize;
PSIZE_T NumberOfBytesRead;
} input = { processHandle, BaseAddress, Buffer, BufferSize, NumberOfBytes };
IO_STATUS_BLOCK ioStatusBlock;
NtDeviceIoControlFile(m_hDriver, nullptr, nullptr, nullptr, &ioStatusBlock, MM_READVIRTUALMEMORY, &input, sizeof(input), nullptr, 0);
}
void MemoryManager::writeMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize) {
if (!allIsWell)
return;
struct {
HANDLE ProcessHandle;
PVOID BaseAddress;
PVOID Buffer;
SIZE_T BufferSize;
PSIZE_T NumberOfBytesWritten;
} input = { processHandle, BaseAddress, Buffer, BufferSize, NumberOfBytesWrite };
IO_STATUS_BLOCK ioStatusBlock;
NtDeviceIoControlFile(m_hDriver, nullptr, nullptr, nullptr, &ioStatusBlock, MM_WRITEVIRTUALMEMORY, &input, sizeof(input), nullptr, 0);
}
bool MemoryManager::search(BYTE * bSearchData, int nSearchSize, DWORD_PTR dwStartAddr, DWORD_PTR dwEndAddr, BOOL bIsCurrProcess, int iSearchMode, std::vector<DWORD_PTR> &vRet){
MEMORY_BASIC_INFORMATION mbi;
std::vector<MEMORY_REGION> m_vMemoryRegion;
mbi.RegionSize = 0x400;
DWORD dwAddress = dwStartAddr;
MEMORY_REGION memSectorList[1000];
int memSectorIndex = 0;
while(VirtualQueryEx(processHandle, (LPCVOID)dwAddress, &mbi, sizeof(mbi)) && (dwAddress < dwEndAddr) && ((dwAddress + mbi.RegionSize) > dwAddress)){
if(
(mbi.State == MEM_COMMIT) &&
((mbi.Protect & PAGE_GUARD) == 0) &&
(mbi.Protect != PAGE_NOACCESS) &&
((mbi.AllocationProtect & PAGE_NOCACHE) != PAGE_NOCACHE)
){
MEMORY_REGION mData = { 0 };
mData.dwBaseAddr = (DWORD_PTR)mbi.BaseAddress;
mData.dwMemorySize = mbi.RegionSize;
m_vMemoryRegion.push_back(mData);
memSectorList[memSectorIndex] = mData;
memSectorIndex++;
}
dwAddress = (DWORD)mbi.BaseAddress + mbi.RegionSize;
}
std::vector<MEMORY_REGION>::iterator it;
int memSectorCount = memSectorIndex;
memSectorIndex = 0;
DWORD_PTR curAddr = dwStartAddr;
while(curAddr < dwEndAddr){
VirtualQueryEx(processHandle, (LPCVOID)curAddr, &mbi, sizeof(mbi));
long regionSizeOrg = mbi.RegionSize;
long regionSize = mbi.RegionSize;
if(regionSize > 10){
BYTE* pCurrMemoryData = new BYTE[regionSize];
ZeroMemory(pCurrMemoryData, regionSize);
writeMemory((PVOID)curAddr, (PVOID*)pCurrMemoryData, regionSize);
DWORD_PTR dwOffset = 0;
int iOffset = find(pCurrMemoryData, regionSize, bSearchData, nSearchSize);
while(iOffset != -1){
dwOffset += iOffset;
vRet.push_back(dwOffset + curAddr);
dwOffset += nSearchSize;
iOffset = find(pCurrMemoryData + dwOffset, regionSize - dwOffset - nSearchSize, bSearchData, nSearchSize);
}
delete[] pCurrMemoryData;
}
memSectorIndex++;
curAddr = curAddr + (DWORD_PTR)regionSizeOrg;
continue;
}
return TRUE;
}
int MemoryManager::find(BYTE *buffer, int dwBufferSize, BYTE *bstr, DWORD dwStrLen){
if(dwBufferSize < 0){
return -1;
}
DWORD i, j;
for(i = 0; i < dwBufferSize; i++){
for(j = 0; j < dwStrLen; j++){
if(buffer[i + j] != bstr[j] && bstr[j] != '?')
break;
}
if(j == dwStrLen)
return i;
}
return -1;
}
DWORD MemoryManager::dRead(DWORD base){
readMemory((PVOID)base, &_d, 4);
return _d;
}
void MemoryManager::dWrite(DWORD base){
writeMemory((PVOID)base, &_d, 4);
}
/* these are in bypassmemory.cpp */
void BypassMemory::init(){
viewWordBase = getAddr(); // = works and gets Addrs = 0x04013118
if(viewWordBase){
std::cout << "found addr : " << termcolor::green << std::hex << viewWordBase << std::dec << termcolor::reset << "\n";
} else{
std::cout << termcolor::red << "View World Not Found ! \n" << termcolor::reset;
return;
}
// so basiclly my addres = 0x04013118 and value of it = DC 04 00 00 04 02 00 00
BYTE writePattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//const char* writePtr = "DC 04 00 00 00 00 00 00"; // i tried also this but didn't work
MemoryManager->writeMemory((PVOID)bypassAddr1, &writePattern, sizeof(writePattern)); // i write to the base addres ( 0x04013118, new val = DC 04 00 00 00 00 00 00)
//MemoryManager->writeMemory((PVOID)bypassAddr1, &writePtr, sizeof(writePtr));
}
DWORD BypassMemory::getAddr(){
BYTE pattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 };
std::vector<DWORD_PTR> foundedBases;
MemoryManager->search(pattern, sizeof(pattern), 0x04000000, 0x05000000, false, 0, foundedBases);
std::cout << "founded bases size: " << termcolor::green << std::hex << foundedBases.size() << std::dec << termcolor::reset << "\n";
for(int i = 0; i < foundedBases.size(); i++){
DWORD cand = dGet(foundedBases[i]); // this reads inside the address purpose to check
std::cout << "founded bases addr: " << termcolor::green << std::hex << foundedBases[i] << std::dec << termcolor::reset << "\n";
return foundedBases[i];
}
return 0;
}
int main()
{
int Pid = ProcManager::getAowProcID();
pMemoryManager->init(Pid, true);
BypassMemory->init();
return 0;
}
这是MemoryManager.h:(如果有人感兴趣的话)
#define MM_DEVICE_TYPE 0x9999
#define MM_CTL_CODE(x) CTL_CODE(MM_DEVICE_TYPE, 0x800 + x, METHOD_NEITHER, FILE_ANY_ACCESS)
#define MM_READVIRTUALMEMORY MM_CTL_CODE(56)
#define MM_WRITEVIRTUALMEMORY MM_CTL_CODE(57)
typedef struct _MEMORY_REGION{
DWORD_PTR dwBaseAddr;
DWORD_PTR dwMemorySize;
}MEMORY_REGION;
class MemoryManager{
public:
MemoryManager();
~MemoryManager();
HANDLE m_hDriver = nullptr;
HANDLE processHandle;
int processId = 0;
bool allIsWell = false;
PSIZE_T NumberOfBytes = nullptr;
PSIZE_T NumberOfBytesWrite = nullptr; // created by oday
DWORD _d;
float _f;
int _i;
BYTE* _b = new BYTE[1];
int _dw = 1245; // created by oday
void init(int pid, bool debug);
bool connectToDriver(std::string m_strDeviceName);
void readMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize);
void writeMemory(PVOID BaseAddress, PVOID Buffer, SIZE_T BufferSize); // created by oday
bool search(BYTE * bSearchData, int nSearchSize, DWORD_PTR dwStartAddr, DWORD_PTR dwEndAddr, BOOL bIsCurrProcess, int iSearchMode, std::vector<DWORD_PTR>& vRet);
int find(BYTE * buffer, int dwBufferSize, BYTE * bstr, DWORD dwStrLen);
void dWrite(DWORD base); // created by oday
DWORD dRead(DWORD base);
float fRead(DWORD base);
int iRead(DWORD base);
BYTE* bRead(DWORD base);
};
extern MemoryManager* pMemoryManager;
有趣的地方在于:
BYTE writePattern[] = { 0xDC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
pMemoryManager->writeMemory((PVOID)bypassAddr1, &writePattern, sizeof(writePattern));
我从当前模式的搜索功能中成功读取了地址 0x04013118,一切正常,但是当我尝试用我在这里提到的内容写入该地址时 内存中什么也没发生,值也没有改变,有人知道为什么什么都没有发生,内存也没有改变吗?我很确定我的内核驱动程序与此无关,因为它存在漏洞并且具有读写权限。
我会为其他有同样问题的人得出一个简短的结论。
主要问题是作者无法写入进程内存中的特定内存位置。
借助 windows API 函数 VirtualProtectEx
作者能够更改虚拟内存页面访问位以允许写入所需内存地址的内存页面.
程序包括:
- 正在调用
VirtualProtectEx
以启用写入内存页面 - 写入该页面中的特定内存位置
- 再次调用
VirtualProtectEx
重置页面访问位