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