DBG: find pattern in the memory map (findallmem startAddr, "1? 24 ?6 78")
This commit is contained in:
parent
156641b0c5
commit
6bb96406b3
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue