1
0
Fork 0

DBG: find pattern in the memory map (findallmem startAddr, "1? 24 ?6 78")

This commit is contained in:
Mr. eXoDia 2015-10-13 22:51:23 +02:00
parent 156641b0c5
commit 6bb96406b3
5 changed files with 189 additions and 2 deletions

View File

@ -31,8 +31,10 @@
#include "analysis_nukem.h"
#include "exceptiondirectoryanalysis.h"
#include "_scriptapi_stack.h"
#include "threading.h"
static bool bRefinit = false;
static int maxFindResults = 5000;
CMDRESULT cbBadCmd(int argc, char* argv[])
{
@ -1240,7 +1242,7 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
dputs("failed to transform pattern!");
return STATUS_ERROR;
}
while(refCount < 5000)
while(refCount < maxFindResults)
{
uint foundoffset = patternfind(data() + start + i, find_size - i, searchpattern);
if(foundoffset == -1)
@ -1277,6 +1279,116 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
return STATUS_CONTINUE;
}
CMDRESULT cbInstrFindMemAll(int argc, char* argv[])
{
dprintf("argc: %d\n", argc);
for(int i = 0; i < argc; i++)
{
dprintf("%d:\"%s\"\n", i, argv[i]);
}
if(argc < 3)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
uint addr = 0;
if(!valfromstring(argv[1], &addr, false))
return STATUS_ERROR;
char pattern[deflen] = "";
//remove # from the start and end of the pattern (ODBGScript support)
if(argv[2][0] == '#')
strcpy_s(pattern, argv[2] + 1);
else
strcpy_s(pattern, argv[2]);
int len = (int)strlen(pattern);
if(pattern[len - 1] == '#')
pattern[len - 1] = '\0';
std::vector<PatternByte> searchpattern;
if(!patterntransform(pattern, searchpattern))
{
dputs("failed to transform pattern!");
return STATUS_ERROR;
}
uint endAddr = -1;
bool findData = false;
if(argc >= 4)
{
if(!_stricmp(argv[3], "&data&"))
findData = true;
else if(!valfromstring(argv[3], &endAddr))
findData = false;
}
SHARED_ACQUIRE(LockMemoryPages);
std::vector<SimplePage> searchPages;
for(auto & itr : memoryPages)
{
SimplePage page(uint(itr.second.mbi.BaseAddress), itr.second.mbi.RegionSize);
if(page.address >= addr && page.address + page.size <= endAddr)
searchPages.push_back(page);
}
SHARED_RELEASE();
DWORD ticks = GetTickCount();
std::vector<uint> results;
if(!MemFindInMap(searchPages, searchpattern, results, maxFindResults))
{
dputs("MemFindInMap failed!");
return STATUS_ERROR;
}
//setup reference view
char patternshort[256] = "";
strncpy_s(patternshort, pattern, min(16, len));
if(len > 16)
strcat_s(patternshort, "...");
char patterntitle[256] = "";
sprintf_s(patterntitle, "Pattern: %s", patternshort);
GuiReferenceInitialize(patterntitle);
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
if(findData)
GuiReferenceAddColumn(0, "&Data&");
else
GuiReferenceAddColumn(0, "Disassembly");
GuiReferenceReloadData();
int refCount = 0;
for(uint result : results)
{
char msg[deflen] = "";
sprintf(msg, fhex, result);
GuiReferenceSetRowCount(refCount + 1);
GuiReferenceSetCellContent(refCount, 0, msg);
if(findData)
{
Memory<unsigned char*> printData(searchpattern.size(), "cbInstrFindAll:printData");
MemRead(result, printData(), printData.size());
for(size_t j = 0, k = 0; j < printData.size(); j++)
{
if(j)
k += sprintf(msg + k, " ");
k += sprintf(msg + k, "%.2X", printData()[j]);
}
}
else
{
if(!GuiGetDisassembly(result, msg))
strcpy_s(msg, "[Error disassembling]");
}
GuiReferenceSetCellContent(refCount, 1, msg);
refCount++;
}
GuiReferenceReloadData();
dprintf("%d occurrences found in %ums\n", refCount, GetTickCount() - ticks);
varset("$result", refCount, false);
return STATUS_CONTINUE;
}
static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!disasm || !basicinfo) //initialize
@ -2159,4 +2271,21 @@ CMDRESULT cbInstrMeminfo(int argc, char* argv[])
dputs("memory map updated!");
}
return STATUS_CONTINUE;
}
CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[])
{
if(argc < 2)
{
dputs("Not enough arguments!");
return STATUS_ERROR;
}
uint num;
if(!valfromstring(argv[1], &num))
{
dprintf("Invalid expression: \"%s\"", argv[1]);
return STATUS_ERROR;
}
maxFindResults = num;
return STATUS_CONTINUE;
}

View File

@ -55,6 +55,7 @@ CMDRESULT cbInstrCopystr(int argc, char* argv[]);
CMDRESULT cbInstrFind(int argc, char* argv[]);
CMDRESULT cbInstrFindAll(int argc, char* argv[]);
CMDRESULT cbInstrFindMemAll(int argc, char* argv[]);
CMDRESULT cbInstrModCallFind(int argc, char* argv[]);
CMDRESULT cbInstrCommentList(int argc, char* argv[]);
CMDRESULT cbInstrLabelList(int argc, char* argv[]);
@ -75,5 +76,6 @@ CMDRESULT cbInstrMeminfo(int argc, char* argv[]);
CMDRESULT cbInstrCfanalyse(int argc, char* argv[]);
CMDRESULT cbInstrExanalyse(int argc, char* argv[]);
CMDRESULT cbInstrVirtualmod(int argc, char* argv[]);
CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]);
#endif // _INSTRUCTIONS_H

View File

@ -471,3 +471,42 @@ bool MemPageRightsFromString(DWORD* Protect, const char* Rights)
return (*Protect != 0);
}
bool MemFindInPage(SimplePage page, uint startoffset, const std::vector<PatternByte> & pattern, std::vector<uint> & results, uint maxresults)
{
if(startoffset >= page.size || results.size() >= maxresults)
return false;
//TODO: memory read limit
Memory<unsigned char*> data(page.size);
if(!MemRead(page.address, data(), data.size()))
return false;
uint maxFind = maxresults;
uint foundCount = results.size();
uint i = 0;
uint findSize = data.size() - startoffset;
while(foundCount < maxFind)
{
uint foundoffset = patternfind(data() + startoffset + i, findSize - i, pattern);
if(foundoffset == -1)
break;
i += foundoffset + 1;
uint result = page.address + startoffset + i - 1;
results.push_back(result);
foundCount++;
}
return true;
}
bool MemFindInMap(const std::vector<SimplePage> & pages, const std::vector<PatternByte> & pattern, std::vector<uint> & results, uint maxresults)
{
for(const auto page : pages)
{
if(!MemFindInPage(page, 0, pattern, results, maxresults))
return false;
if(results.size() >= maxresults)
break;
}
return true;
}

View File

@ -2,10 +2,23 @@
#include "_global.h"
#include "addrinfo.h"
#include "patternfind.h"
extern std::map<Range, MEMPAGE, RangeCompare> memoryPages;
extern bool bListAllPages;
struct SimplePage
{
uint address;
uint size;
SimplePage(uint address, uint size)
{
this->address = address;
this->size = size;
}
};
void MemUpdateMap();
uint MemFindBaseAddr(uint Address, uint* Size, bool Refresh = false);
bool MemRead(uint BaseAddress, void* Buffer, uint Size, uint* NumberOfBytesRead = nullptr);
@ -21,4 +34,6 @@ bool MemGetPageInfo(uint Address, MEMPAGE* PageInfo, bool Refresh = false);
bool MemSetPageRights(uint Address, const char* Rights);
bool MemGetPageRights(uint Address, char* Rights);
bool MemPageRightsToString(DWORD Protect, char* Rights);
bool MemPageRightsFromString(DWORD* Protect, const char* Rights);
bool MemPageRightsFromString(DWORD* Protect, const char* Rights);
bool MemFindInPage(SimplePage page, uint startoffset, const std::vector<PatternByte> & pattern, std::vector<uint> & results, uint maxresults);
bool MemFindInMap(const std::vector<SimplePage> & pages, const std::vector<PatternByte> & pattern, std::vector<uint> & results, uint maxresults);

View File

@ -210,6 +210,8 @@ static void registercommands()
dbgcmdnew("analyse_nukem\1analyze_nukem\1anal_nukem", cbInstrAnalyseNukem, true); //secret analysis command #2
dbgcmdnew("exanal\1exanalyse\1exanalyze", cbInstrExanalyse, true); //exception directory analysis
dbgcmdnew("virtualmod", cbInstrVirtualmod, true); //virtual module
dbgcmdnew("findallmem\1findmemall", cbInstrFindMemAll, true); //memory map pattern find
dbgcmdnew("setmaxfindresult\1findsetmaxresult", cbInstrSetMaxFindResult, false); //set the maximum number of occurences found
}
static bool cbCommandProvider(char* cmd, int maxlen)