예제 #1
0
bool SHMProcess::Private::validate(vector <VersionInfo *> & known_versions)
{
    // try to identify the DF version
    IMAGE_NT_HEADERS32 pe_header;
    IMAGE_SECTION_HEADER sections[16];
    HMODULE hmod = NULL;
    DWORD junk;
    HANDLE hProcess;
    bool found = false;
    identified = false;
    // open process, we only need the process open
    hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, process_ID );
    if (NULL == hProcess)
        return false;

    // try getting the first module of the process
    if(EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk) == 0)
    {
        CloseHandle(hProcess);
        // cout << "EnumProcessModules fail'd" << endl;
        return false;
    }
    // got base ;)
    uint32_t base = (uint32_t)hmod;

    // read from this process
    uint32_t pe_offset = self->readDWord(base+0x3C);
    self->read(base + pe_offset                   , sizeof(pe_header), (uint8_t *)&pe_header);
    self->read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)&sections );

    // iterate over the list of memory locations
    vector<VersionInfo *>::iterator it;
    for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
    {
        uint32_t pe_timestamp;
        try
        {
            pe_timestamp = (*it)->getPE();
        }
        catch(Error::MissingMemoryDefinition&)
        {
            continue;
        }
        if (pe_timestamp == pe_header.FileHeader.TimeDateStamp)
        {
            VersionInfo *m = new VersionInfo(**it);
            m->RebaseAll(base);
            memdescriptor = m;
            m->setParentProcess(self);
            identified = true;
            cerr << "identified " << m->getVersion() << endl;
            CloseHandle(hProcess);
            return true;
        }
    }
    return false;
}
예제 #2
0
NormalProcess::NormalProcess(uint32_t pid, vector <VersionInfo *> & known_versions)
: d(new Private())
{
    HMODULE hmod = NULL;
    DWORD junk;
    HANDLE hProcess;
    bool found = false;

    IMAGE_NT_HEADERS32 pe_header;
    IMAGE_SECTION_HEADER sections[16];
    d->identified = false;
    // open process
    hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
    if (NULL == hProcess)
        return;

    // try getting the first module of the process
    if(EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk) == 0)
    {
        CloseHandle(hProcess);
        // cout << "EnumProcessModules fail'd" << endl;
        return; //if enumprocessModules fails, give up
    }

    // got base ;)
    uint32_t base = (uint32_t)hmod;

    // temporarily assign this to allow some checks
    d->my_handle = hProcess;
    d->my_main_thread = 0;
    // read from this process
    try
    {
        uint32_t pe_offset = readDWord(base+0x3C);
        read(base + pe_offset                   , sizeof(pe_header), (uint8_t *)&pe_header);
        read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)&sections );
        d->my_handle = 0;
    }
    catch (exception &)
    {
        CloseHandle(hProcess);
        d->my_handle = 0;
        return;
    }

    // see if there's a version entry that matches this process
    vector<VersionInfo*>::iterator it;
    for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
    {
        // filter by OS
        if(VersionInfo::OS_WINDOWS != (*it)->getOS())
            continue;
        uint32_t pe_timestamp;
        // filter by timestamp, skip entries without a timestamp
        try
        {
            pe_timestamp = (*it)->getPE();
        }
        catch(Error::MissingMemoryDefinition&)
        {
            continue;
        }
        if (pe_timestamp != pe_header.FileHeader.TimeDateStamp)
            continue;

        // all went well
        {
            printf("Match found! Using version %s.\n", (*it)->getVersion().c_str());
            d->identified = true;
            // give the process a data model and memory layout fixed for the base of first module
            VersionInfo *m = new VersionInfo(**it);
            m->RebaseAll(base);
            // keep track of created memory_info object so we can destroy it later
            d->my_descriptor = m;
            m->setParentProcess(this);
            // process is responsible for destroying its data model
            d->my_pid = pid;
            d->my_handle = hProcess;
            d->identified = true;

            // TODO: detect errors in thread enumeration
            vector<uint32_t> threads;
            getThreadIDs( threads );
            d->my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]);
            OffsetGroup * strGrp = m->getGroup("string")->getGroup("MSVC");
            d->STLSTR_buf_off = strGrp->getOffset("buffer");
            d->STLSTR_size_off = strGrp->getOffset("size");
            d->STLSTR_cap_off = strGrp->getOffset("capacity");
            found = true;
            break; // break the iterator loop
        }
    }
    // close handle of processes that aren't DF
    if(!found)
    {
        CloseHandle(hProcess);
    }
}