Add searchOpcode tag for !jutsu
git-svn-id: file:///home/svn/framework3/trunk@5642 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
b6993ad46a
commit
2a093a3f2a
|
@ -78,6 +78,18 @@ D. Usage:
|
||||||
f. Use !jutsu findReturn to find valid return addresses
|
f. Use !jutsu findReturn to find valid return addresses
|
||||||
1. hunt will use all knowledge about controlled registers and buffer offsets
|
1. hunt will use all knowledge about controlled registers and buffer offsets
|
||||||
to find all possible usable return addresses
|
to find all possible usable return addresses
|
||||||
|
g. Use !jutsu searchOpcode to fine opcodes in executable memory
|
||||||
|
1. delimit instructions with pipes - example:
|
||||||
|
|
||||||
|
0:000> !jutsu searchOpcode pop ecx | pop ecx | ret
|
||||||
|
[J] Searching for:
|
||||||
|
> pop ecx
|
||||||
|
> pop ecx
|
||||||
|
> ret
|
||||||
|
[J] Machine Code:
|
||||||
|
> 59 59 c3
|
||||||
|
[J] Opcode sequence found at: 0x004012f9
|
||||||
|
|
||||||
3. Mushishi (Anti-debugging detection / removal)
|
3. Mushishi (Anti-debugging detection / removal)
|
||||||
a. Not much in here now, but growing
|
a. Not much in here now, but growing
|
||||||
b. !mushishi detect - detects several methods
|
b. !mushishi detect - detects several methods
|
||||||
|
|
|
@ -97,6 +97,13 @@ HRESULT CALLBACK jutsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
helpJutsu();
|
helpJutsu();
|
||||||
return (S_OK);
|
return (S_OK);
|
||||||
}
|
}
|
||||||
|
if (!_stricmp(command, "searchOpcode")) {
|
||||||
|
char *instructions;
|
||||||
|
|
||||||
|
instructions = (char *) args + strlen(command) + 1;
|
||||||
|
searchOpcodes(instructions);
|
||||||
|
return (S_OK);
|
||||||
|
}
|
||||||
if (!_stricmp(command, "listen")) {
|
if (!_stricmp(command, "listen")) {
|
||||||
bindPort = strtok(NULL, " ");
|
bindPort = strtok(NULL, " ");
|
||||||
if (bindPort == NULL)
|
if (bindPort == NULL)
|
||||||
|
|
|
@ -413,30 +413,39 @@ unsigned short getInstructionBytes(char * instruction, unsigned char * opcodeBuf
|
||||||
ULONG64 byteEnd = 0;
|
ULONG64 byteEnd = 0;
|
||||||
BYTE i = 0;
|
BYTE i = 0;
|
||||||
|
|
||||||
|
if(!disassemblyBuffer){
|
||||||
|
if(!(disassemblyBuffer = allocateMemoryBlock(0x1000))){
|
||||||
|
dprintf("[J] allocateMemoryBlock failed\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(g_ExtControl->Assemble(disassemblyBuffer, instruction, &byteEnd) != S_OK){
|
if(g_ExtControl->Assemble(disassemblyBuffer, instruction, &byteEnd) != S_OK){
|
||||||
dprintf("[J] failed to assemble instruction\n");
|
dprintf("[J] failed to assemble instruction\n");
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ReadMemory(disassemblyBuffer, opcodeBuffer, (byteEnd-disassemblyBuffer), NULL)){
|
if(!ReadMemory(disassemblyBuffer, opcodeBuffer, (byteEnd-disassemblyBuffer), NULL)){
|
||||||
dprintf("[J] failed to read opcode sequence\n");
|
dprintf("[J] failed to read opcode sequence\n");
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<(byteEnd-disassemblyBuffer); i++){
|
for(i=0; i<(byteEnd-disassemblyBuffer); i++){
|
||||||
if(!WriteMemory((disassemblyBuffer+i), &zero, 1, NULL)){
|
if(!WriteMemory((disassemblyBuffer+i), &zero, 1, NULL)){
|
||||||
dprintf("[J] failed to zero memory\n");
|
dprintf("[J] failed to zero memory\n");
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
//dprintf("[J] Opcode sequence for instruction %s:", instruction);
|
dprintf("[J] Opcode sequence for instruction %s:", instruction);
|
||||||
|
|
||||||
for(byteCounter=0; ((disassemblyBuffer+byteCounter)<byteEnd); byteCounter++){
|
for(byteCounter=0; ((disassemblyBuffer+byteCounter)<byteEnd); byteCounter++){
|
||||||
dprintf("%02x ", opcodeBuffer[byteCounter]);
|
dprintf("%02x ", opcodeBuffer[byteCounter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
|
#endif
|
||||||
return (byteEnd-disassemblyBuffer);
|
return (byteEnd-disassemblyBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,9 +463,11 @@ ULONG64 searchMemory(unsigned char * byteBuffer, unsigned long length){
|
||||||
dprintf("[J] byte search failed for another reason\n");
|
dprintf("[J] byte search failed for another reason\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
return addressHit;
|
if (!(addressHit >= disassemblyBuffer && addressHit <= (disassemblyBuffer+0x1000)))
|
||||||
|
return (addressHit);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL checkExecutability(ULONG64 checkAddress){
|
BOOL checkExecutability(ULONG64 checkAddress){
|
||||||
|
@ -467,16 +478,76 @@ BOOL checkExecutability(ULONG64 checkAddress){
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("allocation info: 0x%08x and 0x%08x\n", protectionInfo.AllocationProtect, protectionInfo.Protect);
|
//dprintf("allocation info: 0x%08x and 0x%08x\n", protectionInfo.AllocationProtect, protectionInfo.Protect);
|
||||||
|
|
||||||
if((protectionInfo.Protect & PAGE_EXECUTE_READ) != 0)
|
if((protectionInfo.Protect & PAGE_EXECUTE_READ) != 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
dprintf("[J] 0x%08x isn't executable\n");
|
//dprintf("[J] 0x%08x isn't executable\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void searchOpcodes(char *instructions) {
|
||||||
|
char **instructionList;
|
||||||
|
unsigned char *byteSequence;
|
||||||
|
DWORD length, i, j, semiCount = 1, offset = 0;
|
||||||
|
ULONG64 ptr;
|
||||||
|
|
||||||
|
// Split instructions into seperate strings at pipes
|
||||||
|
length = 0;
|
||||||
|
while (instructions[length] != NULL) {
|
||||||
|
if (instructions[length] == '|')
|
||||||
|
semiCount++;
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Malloc space for instructionList;
|
||||||
|
instructionList = (char **) malloc((semiCount+1) * sizeof (char *));
|
||||||
|
if (instructionList == NULL) {
|
||||||
|
dprintf("[J] OOM!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
instructionList[0] = instructions;
|
||||||
|
dprintf("[J] Searching for:\n");
|
||||||
|
i = 0; j = 0;
|
||||||
|
while (i < length) {
|
||||||
|
if (instructions[i] == '|') {
|
||||||
|
instructions[i] = '\x00';
|
||||||
|
dprintf("> %s\n", instructionList[j++]);
|
||||||
|
instructionList[j] = &(instructions[i+1]);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dprintf("> %s\n", instructionList[j]);
|
||||||
|
|
||||||
|
|
||||||
|
// Allocate space for byteSequence
|
||||||
|
byteSequence = (unsigned char *) malloc(semiCount * 6);
|
||||||
|
if (byteSequence == NULL) {
|
||||||
|
dprintf("[J] OOM!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate byte sequence and display it
|
||||||
|
for (i = 0; i < semiCount; i++) {
|
||||||
|
unsigned char tmpbuf[8];
|
||||||
|
offset += getInstructionBytes(instructionList[i], byteSequence+offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("[J] Machine Code:\n> ");
|
||||||
|
for (i = 0; i < offset; i++) {
|
||||||
|
dprintf("%02x ", byteSequence[i]);
|
||||||
|
if (i != 0 && !(i % 16))
|
||||||
|
dprintf("\n> ");
|
||||||
|
}
|
||||||
|
dprintf("\n");
|
||||||
|
|
||||||
|
// Search for sequence in executable memory
|
||||||
|
ptr = searchMemory(byteSequence, offset);
|
||||||
|
if (ptr && checkExecutability(ptr))
|
||||||
|
dprintf("[J] Executable opcode sequence found at: 0x%08x\n", ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void returnAddressHuntJutsu(){
|
void returnAddressHuntJutsu(){
|
||||||
struct trackedBuf *curBuf;
|
struct trackedBuf *curBuf;
|
||||||
|
@ -492,15 +563,6 @@ void returnAddressHuntJutsu(){
|
||||||
unsigned short instructionLength = 0;
|
unsigned short instructionLength = 0;
|
||||||
dprintf("[J] started return address hunt\n");
|
dprintf("[J] started return address hunt\n");
|
||||||
|
|
||||||
//this part might need to be changed
|
|
||||||
if(!disassemblyBuffer){
|
|
||||||
if(!(disassemblyBuffer = allocateMemoryBlock(0x1000))){
|
|
||||||
dprintf("[J] allocateMemoryBlock failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("opcode test buffer starts at 0x%08x\n", disassemblyBuffer);
|
|
||||||
|
|
||||||
for(i; i<6; i++){ //6, because we don't want to waste time on the eip register
|
for(i; i<6; i++){ //6, because we don't want to waste time on the eip register
|
||||||
curBuf = trackedBufList;
|
curBuf = trackedBufList;
|
||||||
|
|
|
@ -59,6 +59,7 @@ struct bufInstance {
|
||||||
|
|
||||||
void helpJutsu(void);
|
void helpJutsu(void);
|
||||||
void bindJutsu(char *);
|
void bindJutsu(char *);
|
||||||
|
void searchOpcodes(char *);
|
||||||
DWORD WINAPI listenJutsu(LPVOID lpvParam);
|
DWORD WINAPI listenJutsu(LPVOID lpvParam);
|
||||||
void parseJutsu(char *, ULONG);
|
void parseJutsu(char *, ULONG);
|
||||||
void identBufJutsu(char *, char *);
|
void identBufJutsu(char *, char *);
|
||||||
|
|
Loading…
Reference in New Issue