0

所以我会解释我想做什么,我想了解为什么它不适合我,

我从 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 处的地址,一切都很好,但是当我尝试用我在这里提到的这个地址写入这个地址时,内存中没有任何反应,并且值不会改变,有没有人知道为什么什么都没有发生并且记忆没有改变?我很确定我的内核驱动程序与此无关,因为它的漏洞并且它具有读写权限。

4

1 回答 1

2

我将为遇到同样问题的其他人得出一个简短的结论。

主要问题是作者无法写入进程内存中的特定内存位置。

在 Windows API 函数的帮助下,VirtualProtectEx作者能够更改虚拟内存页面访问位以允许写入所需内存地址的内存页面。

该程序包括:

  1. 调用VirtualProtectEx以启用对内存页面的写入
  2. 写入该页面中的特定内存位置
  3. 使用另一个调用重置页面访问位VirtualProtectEx
于 2020-09-01T11:42:10.287 回答