* r_anal // r_asm
- Initial AOP parser (needs more love) - Adds buf and inst_len to r_asm_t - Refactoring * More Makefile refactoring
This commit is contained in:
parent
710adba920
commit
389cce05f6
16 changed files with 528 additions and 35 deletions
|
|
@ -3,7 +3,7 @@
|
|||
struct r_anal_t *r_anal_new()
|
||||
{
|
||||
struct r_anal_t *a = MALLOC_STRUCT(struct r_anal_t);
|
||||
r_asm_init(a);
|
||||
r_anal_init(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
@ -16,3 +16,4 @@ int r_anal_init(struct r_anal_t *a)
|
|||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ CFLAGS+=-DLIL_ENDIAN=1
|
|||
# X86
|
||||
OBJ+=arch/x86/asm.o
|
||||
OBJ+=arch/x86/pseudo.o
|
||||
OBJ+=arch/x86/aop.o
|
||||
OBJ+=arch/x86/realloc.o
|
||||
# udis86
|
||||
OBJ+=arch/x86/udis86/syn.o
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ static int buf_fprintf(void *stream, const char *format, ...)
|
|||
int r_asm_arm_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
||||
{
|
||||
struct disassemble_info disasm_obj;
|
||||
int ret;
|
||||
|
||||
buf_global = a->buf_asm;
|
||||
Offset = a->pc;
|
||||
|
|
@ -79,10 +78,13 @@ int r_asm_arm_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
disasm_obj.stream = stdout;
|
||||
|
||||
a->buf_asm[0]='\0';
|
||||
ret = print_insn_arm((bfd_vma)Offset, &disasm_obj);
|
||||
a->inst_len = print_insn_arm((bfd_vma)Offset, &disasm_obj);
|
||||
|
||||
if (ret == -1)
|
||||
if (a->inst_len == -1)
|
||||
strcpy(a->buf_asm, " (data)");
|
||||
|
||||
return ret;
|
||||
if (a->inst_len > 0)
|
||||
memcpy(a->buf, buf, a->inst_len);
|
||||
|
||||
return a->inst_len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ static int buf_fprintf(void *stream, const char *format, ...)
|
|||
int r_asm_mips_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
||||
{
|
||||
struct disassemble_info disasm_obj;
|
||||
int ret;
|
||||
|
||||
buf_global = a->buf_asm;
|
||||
Offset = a->pc;
|
||||
|
|
@ -81,11 +80,14 @@ int r_asm_mips_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
|
||||
a->buf_asm[0]='\0';
|
||||
if (a->big_endian)
|
||||
ret = print_insn_big_mips((bfd_vma)Offset, &disasm_obj);
|
||||
else ret = print_insn_little_mips((bfd_vma)Offset, &disasm_obj);
|
||||
a->inst_len = print_insn_big_mips((bfd_vma)Offset, &disasm_obj);
|
||||
else a->inst_len = print_insn_little_mips((bfd_vma)Offset, &disasm_obj);
|
||||
|
||||
if (ret == -1)
|
||||
if (a->inst_len == -1)
|
||||
strcpy(a->buf_asm, " (data)");
|
||||
|
||||
return ret;
|
||||
if (a->inst_len > 0)
|
||||
memcpy(a->buf, buf, a->inst_len);
|
||||
|
||||
return a->inst_len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ int r_asm_ppc_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
PPC_Disassemble(&dp, a->big_endian);
|
||||
r_hex_bin2str((u8*)bof, 4, a->buf_hex);
|
||||
sprintf(a->buf_asm, "%s %s", opcode, operands);
|
||||
memcpy(a->buf, buf, 4);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ static int buf_fprintf(void *stream, const char *format, ...)
|
|||
int r_asm_sparc_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
||||
{
|
||||
struct disassemble_info disasm_obj;
|
||||
int ret;
|
||||
|
||||
buf_global = a->buf_asm;
|
||||
Offset = a->pc;
|
||||
|
|
@ -78,10 +77,13 @@ int r_asm_sparc_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
disasm_obj.stream = stdout;
|
||||
|
||||
a->buf_asm[0]='\0';
|
||||
ret = print_insn_sparc((bfd_vma)Offset, &disasm_obj);
|
||||
a->inst_len = print_insn_sparc((bfd_vma)Offset, &disasm_obj);
|
||||
|
||||
if (ret == -1)
|
||||
if (a->inst_len == -1)
|
||||
strcpy(a->buf_asm, " (data)");
|
||||
|
||||
return ret;
|
||||
if (a->inst_len > 0)
|
||||
memcpy(a->buf, buf, a->inst_len);
|
||||
|
||||
return a->inst_len;
|
||||
}
|
||||
|
|
|
|||
422
libr/asm/arch/x86/aop.c
Normal file
422
libr/asm/arch/x86/aop.c
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
/*
|
||||
* Copyright (C) 2007, 2008
|
||||
* pancake <youterm.com>
|
||||
* esteve <eslack.org>
|
||||
*
|
||||
* radare is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* radare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with radare; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* code analysis functions */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
|
||||
/* arch_aop for x86 */
|
||||
|
||||
|
||||
// CMP ARG1
|
||||
// 837d0801 cmp dword [ebp+0x8], 0x1
|
||||
// SET VAR_41c
|
||||
// 8985e4fbffff mov [ebp-41C],eax
|
||||
// GET VAR_41c
|
||||
// 8b85e4fbffff mov eax,[ebp-41C]
|
||||
// 8b450c mov eax,[ebp+C]
|
||||
// 8d85e8fbffff lea eax,[ebp-418]
|
||||
// c68405e7fbffff. mov byte ptr [ebp+eax-419],0x0
|
||||
|
||||
|
||||
// NOTE: buf should be at least 16 bytes!
|
||||
// XXX addr should be off_t for 64 love
|
||||
int r_asm_x86_aop(struct r_asm_t *a)
|
||||
{
|
||||
struct r_anal_aop_t *aop = a->aux;
|
||||
u8 *buf = a->buf;
|
||||
|
||||
memset(aop, '\0', sizeof(struct r_anal_aop_t));
|
||||
aop->type = R_ANAL_AOP_TYPE_UNK;
|
||||
|
||||
switch(buf[0]) {
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
case 0x03: // 034518 add eax, [ebp+0x18]
|
||||
switch(buf[1]) {
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x55:
|
||||
/* mov -0xc(%ebp, %eax */
|
||||
aop->ref = (u64)(int)(-((char)buf[2]));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
break;
|
||||
|
||||
case 0x95:
|
||||
if (buf[2]==0xe0) { // ebp
|
||||
aop->ref = (u64)(-((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24))));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
}
|
||||
//aop->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
break;
|
||||
case 0xbd:
|
||||
aop->ref = (u64)(-((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))));
|
||||
//aop->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x88:
|
||||
case 0x89: // move
|
||||
switch(buf[1]) {
|
||||
case 0x45:
|
||||
case 0x4d: // 894de0 mov [ebp-0x20], ecx
|
||||
case 0x55:
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_SET;
|
||||
aop->ref = (u64)-((char)buf[2]);
|
||||
break;
|
||||
case 0x85:
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_SET;
|
||||
aop->ref = (u64)-((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
break;
|
||||
case 0x75:
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
aop->ref = (u64)(buf[2]); //+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
break;
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
aop->length = 2;
|
||||
break;
|
||||
case 0xf4: // hlt
|
||||
aop->type = R_ANAL_AOP_TYPE_RET;
|
||||
aop->length = 1;
|
||||
break;
|
||||
case 0xc3: // ret
|
||||
case 0xc2: // ret + 2 buf
|
||||
case 0xcb: // lret
|
||||
case 0xcf: // iret
|
||||
aop->type = R_ANAL_AOP_TYPE_RET;
|
||||
// aop->length = 1;
|
||||
aop->eob = 1;
|
||||
break;
|
||||
//case 0xea: // far jmp
|
||||
// TODO moar
|
||||
case 0x3b: //cmp
|
||||
aop->ref = (u64)(-((char)buf[2]));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
case 0x39:
|
||||
case 0x3c:
|
||||
case 0x3d:
|
||||
case 0x85:
|
||||
aop->type = R_ANAL_AOP_TYPE_CMP;
|
||||
aop->length = 2;
|
||||
break;
|
||||
case 0x90:
|
||||
aop->type = R_ANAL_AOP_TYPE_NOP;
|
||||
aop->length = 1;
|
||||
break;
|
||||
case 0x0f: // 3 byte nop
|
||||
//0fbe55ff movsx edx, byte [ebp-0x1]
|
||||
if (buf[1]==0xbe) {
|
||||
aop->ref = (u64)(int)(-((char)buf[3]));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
} else
|
||||
if (buf[1]==0x31) {
|
||||
// RDTSC // colorize or sthg?
|
||||
aop->eob = 0;
|
||||
} else
|
||||
if (buf[1]>=0x18 && buf[1]<=0x1f) {
|
||||
aop->type = R_ANAL_AOP_TYPE_NOP;
|
||||
aop->length = 3;
|
||||
} else
|
||||
if (buf[1]>=0x80 && buf[1]<=0x8f) {
|
||||
aop->type = R_ANAL_AOP_TYPE_CJMP;
|
||||
aop->jump = a->pc+6+buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = a->pc+6;
|
||||
aop->length = 6;
|
||||
//aop->eob = 1;
|
||||
}
|
||||
break;
|
||||
case 0xcc: // int3
|
||||
aop->eob = 1;
|
||||
case 0xf1: // int1
|
||||
aop->length = 1;
|
||||
aop->type = R_ANAL_AOP_TYPE_SWI;
|
||||
break;
|
||||
case 0xcd:
|
||||
aop->length = 2;
|
||||
aop->type = R_ANAL_AOP_TYPE_SWI;
|
||||
break;
|
||||
case 0xe8: // call
|
||||
aop->type = R_ANAL_AOP_TYPE_CALL;
|
||||
aop->length = 5;
|
||||
//aop->jump = a->pc+*ptr+5; //(unsigned long)((buf+1)+5);
|
||||
aop->jump = a->pc+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = a->pc+5;
|
||||
//printf("a->pc: %08llx\n call %08llx \n ret %08llx\n", a->pc, aop->jump, aop->fail);
|
||||
// aop->eob = 1;
|
||||
break;
|
||||
case 0xe9: // jmp
|
||||
aop->type = R_ANAL_AOP_TYPE_JMP;
|
||||
aop->length = 5;
|
||||
//aop->jump = (unsigned long)((buf+1)+5);
|
||||
aop->jump = a->pc+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = 0L;
|
||||
aop->eob = 1;
|
||||
break;
|
||||
case 0xeb: // short jmp
|
||||
aop->type = R_ANAL_AOP_TYPE_JMP;
|
||||
aop->length = 2;
|
||||
aop->jump = a->pc+((unsigned long)((char)buf[1])+2);
|
||||
aop->fail = 0L;
|
||||
aop->eob = 1;
|
||||
break;
|
||||
case 0xf2: // repnz
|
||||
case 0xf3: // repz
|
||||
aop->type = R_ANAL_AOP_TYPE_REP;
|
||||
aop->jump = 0L;
|
||||
aop->fail = 0L;
|
||||
break;
|
||||
case 0xff:
|
||||
if (buf[1]== 0x75) {
|
||||
aop->type = R_ANAL_AOP_TYPE_PUSH;
|
||||
aop->stackop = R_ANAL_STACK_ARG_GET;
|
||||
aop->ref = 0LL;
|
||||
aop->ref = (u64)(((char)(buf[2])));
|
||||
} else
|
||||
if (buf[1]== 0x45) {
|
||||
aop->type = R_ANAL_AOP_TYPE_ADD;
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_SET;
|
||||
aop->ref = (u64)(-((char)buf[2]));
|
||||
} else
|
||||
if (buf[1]>=0x50 && buf[1]<=0x6f) {
|
||||
aop->type = R_ANAL_AOP_TYPE_UJMP;
|
||||
aop->eob = 1;
|
||||
} else
|
||||
if (buf[1]>=0xd0 && buf[1]<=0xd7) {
|
||||
aop->type = R_ANAL_AOP_TYPE_CALL;
|
||||
aop->length = 2;
|
||||
aop->eob = 1;
|
||||
//aop->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
aop->fail = a->pc+2;
|
||||
} else
|
||||
if (buf[1]>=0xe0 && buf[1]<=0xe7) {
|
||||
aop->type = R_ANAL_AOP_TYPE_UJMP;
|
||||
aop->length = 2;
|
||||
//aop->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
aop->eob = 1;
|
||||
}
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
aop->type = R_ANAL_AOP_TYPE_UPUSH;
|
||||
aop->ref = 0; // TODO value of register here! get_offset
|
||||
break;
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
aop->type = R_ANAL_AOP_TYPE_POP;
|
||||
aop->length = 1;
|
||||
break;
|
||||
case 0x68:
|
||||
aop->type = R_ANAL_AOP_TYPE_PUSH;
|
||||
aop->ref = buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0x81:
|
||||
if (buf[1] == 0xec) {
|
||||
/* sub $0x????????, $esp*/
|
||||
// 81ece00d0000 sub esp, 0xde0 ;
|
||||
aop->value = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
break;
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_ADD;
|
||||
break;
|
||||
case 0x83:
|
||||
switch(buf[1]) {
|
||||
case 0xe4: // and
|
||||
aop->value = (u64)(unsigned char)buf[2];
|
||||
aop->type = R_ANAL_AOP_TYPE_AND;
|
||||
break;
|
||||
case 0xc4:
|
||||
/* inc $0x????????, $esp*/
|
||||
aop->value = -(u64)(unsigned char)buf[2];
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
break;
|
||||
case 0xec:
|
||||
/* sub $0x????????, $esp*/
|
||||
aop->value = (u64)(unsigned char)buf[2];
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
break;
|
||||
case 0xbd: /* 837dfc02 cmp dword [ebp-0x4], 0x2 */
|
||||
switch(buf[2]) {
|
||||
case 0xe0: // ebp
|
||||
if ((char)buf[2]>0) {
|
||||
aop->stackop = R_ANAL_STACK_ARG_GET;
|
||||
aop->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
} else {
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
aop->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_CMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x7d: /* 837dfc02 cmp dword [ebp-0x4], 0x2 */
|
||||
if ((char)buf[2]>0) {
|
||||
aop->stackop = R_ANAL_STACK_ARG_GET;
|
||||
aop->value = (u64)(char)buf[2];
|
||||
} else {
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
aop->value = (u64)-(char)buf[2];
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_CMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x8d:
|
||||
/* LEA */
|
||||
if (buf[1] == 0x85) {
|
||||
aop->ref = (u64)(-((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))));
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_GET;
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
break;
|
||||
case 0xc7:
|
||||
|
||||
/* mov dword [ebp-0xc], 0x0 || c7 45 f4 00000000 */
|
||||
switch(buf[1]) {
|
||||
case 0x85:
|
||||
aop->ref = (u64)(((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))));
|
||||
break;
|
||||
//c785 e4fbffff 00. mov dword [ebp+0xfffffbe4], 0x0
|
||||
case 0x45:
|
||||
aop->stackop = R_ANAL_STACK_LOCAL_SET;
|
||||
aop->ref = (u64)(-((char)buf[2]));
|
||||
break;
|
||||
case 0x04:
|
||||
// c7042496850408 dword [esp] = 0x8048596 ; LOL
|
||||
aop->ref = (u64)(((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24))));
|
||||
break;
|
||||
}
|
||||
aop->type = R_ANAL_AOP_TYPE_STORE;
|
||||
break;
|
||||
case 0x82:
|
||||
aop->type = R_ANAL_AOP_TYPE_ADD;
|
||||
break;
|
||||
case 0x29:
|
||||
aop->type = R_ANAL_AOP_TYPE_SUB;
|
||||
break;
|
||||
case 0x31:
|
||||
aop->type = R_ANAL_AOP_TYPE_XOR;
|
||||
break;
|
||||
case 0x32:
|
||||
aop->type = R_ANAL_AOP_TYPE_AND;
|
||||
break;
|
||||
|
||||
case 0xa1: // mov eax, [addr]
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EAX] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
//radare_read_at((u64)vm_arch_x86_regs[VM_X86_EAX], (unsigned char *)&(vm_arch_x86_regs[VM_X86_EAX]), 4);
|
||||
break;
|
||||
|
||||
// roll to a switch range case
|
||||
case 0xb8: // mov eax, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EAX] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0xb9: // mov ecx, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_ECX] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0xba: // mov edx, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EDX] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0xbb: // mov ebx, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EBX] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0xbc: // mov esp, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_ESP] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
case 0xbd: // mov esp, <inmedate>
|
||||
aop->type = R_ANAL_AOP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EBP] = a->pc+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
break;
|
||||
#if 0
|
||||
case0xF
|
||||
/* conditional jump */
|
||||
if (buf[1]>=0x80&&buf[1]<=0x8F) {
|
||||
aop->type = R_ANAL_AOP_TYPE_CJMP;
|
||||
aop->length = 6;
|
||||
aop->jump = (unsigned long)((buf+2)+6);
|
||||
aop->fail = addr+6;
|
||||
aop->eob = 1;
|
||||
return 5;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7a:
|
||||
case 0x7b:
|
||||
case 0x7c:
|
||||
case 0x7d:
|
||||
case 0x7e:
|
||||
case 0x7f: {
|
||||
int bo = (int)((char) buf[1]);
|
||||
/* conditional jump */
|
||||
//if (buf[1]>=0x80&&buf[1]<=0x8F) {
|
||||
aop->type = R_ANAL_AOP_TYPE_CJMP;
|
||||
aop->length = 2;
|
||||
// aop->jump = (unsigned long)((buf+2)+6);
|
||||
aop->jump = a->pc+bo+2; //(unsigned long)((buf+1)+5);
|
||||
aop->fail = a->pc+2;
|
||||
aop->eob = 1;
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
//default:
|
||||
//aop->type = R_ANAL_AOP_TYPE_UNK;
|
||||
}
|
||||
|
||||
aop->length = a->inst_len;
|
||||
|
||||
if (!(aop->jump>>33))
|
||||
aop->jump &= 0xFFFFFFFF; // XXX may break on 64 bits here
|
||||
|
||||
return aop->length;
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ int r_asm_x86_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
ud_t ud;
|
||||
t_disasm olly;
|
||||
} disasm_obj;
|
||||
int ret = 0;
|
||||
|
||||
switch (a->syntax) {
|
||||
case R_ASM_SYN_INTEL:
|
||||
|
|
@ -30,21 +29,24 @@ int r_asm_x86_disasm(struct r_asm_t *a, u8 *buf, u64 len)
|
|||
ud_set_pc(&disasm_obj.ud, a->pc);
|
||||
ud_set_input_buffer(&disasm_obj.ud, buf, len);
|
||||
ud_disassemble(&disasm_obj.ud);
|
||||
a->inst_len = ud_insn_len(&disasm_obj.ud);
|
||||
snprintf(a->buf_asm, 256, "%s", ud_insn_asm(&disasm_obj.ud));
|
||||
snprintf(a->buf_hex, 256, "%s", ud_insn_hex(&disasm_obj.ud));
|
||||
ret = ud_insn_len(&disasm_obj.ud);
|
||||
break;
|
||||
case R_ASM_SYN_OLLY:
|
||||
lowercase=1;
|
||||
ret = Disasm(buf, len, a->pc, &disasm_obj.olly, DISASM_FILE);
|
||||
a->inst_len = Disasm(buf, len, a->pc, &disasm_obj.olly, DISASM_FILE);
|
||||
snprintf(a->buf_asm, 256, "%s", disasm_obj.olly.result);
|
||||
snprintf(a->buf_hex, 256, "%s", disasm_obj.olly.dump);
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
a->inst_len = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (a->inst_len > 0)
|
||||
memcpy(a->buf, buf, a->inst_len);
|
||||
|
||||
return a->inst_len;
|
||||
}
|
||||
|
||||
int r_asm_x86_asm(struct r_asm_t *a, char *buf)
|
||||
|
|
@ -52,30 +54,33 @@ int r_asm_x86_asm(struct r_asm_t *a, char *buf)
|
|||
union {
|
||||
t_asmmodel olly;
|
||||
} asm_obj;
|
||||
int idx, ret = 0;
|
||||
int idx;
|
||||
|
||||
switch (a->syntax) {
|
||||
case R_ASM_SYN_INTEL:
|
||||
case R_ASM_SYN_ATT:
|
||||
/* TODO: Use gas for assembling */
|
||||
ret = 0;
|
||||
a->inst_len = 0;
|
||||
break;
|
||||
case R_ASM_SYN_OLLY:
|
||||
a->buf_err[0] = '\0';
|
||||
/* constsize == 0: Address constants and inmediate data of 16/32b */
|
||||
/* attempt == 0: First attempt */
|
||||
ret = Assemble(buf, a->pc, &asm_obj.olly, 0, 0, a->buf_err);
|
||||
a->inst_len = Assemble(buf, a->pc, &asm_obj.olly, 0, 0, a->buf_err);
|
||||
if (a->buf_err[0])
|
||||
ret = 0;
|
||||
a->inst_len = 0;
|
||||
else {
|
||||
snprintf(a->buf_asm, 256, "%s", buf);
|
||||
for (idx = 0; idx < ret; idx++)
|
||||
for (idx = 0; idx < a->inst_len; idx++)
|
||||
sprintf(a->buf_hex+idx*2, "%02x", (u8)asm_obj.olly.code[idx]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
a->inst_len = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (a->inst_len > 0)
|
||||
memcpy(a->buf, buf, a->inst_len);
|
||||
|
||||
return a->inst_len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
static int r_asm_x86_aop(int argc, const char *argv[], char *newstr)
|
||||
static int r_asm_x86_replace(int argc, const char *argv[], char *newstr)
|
||||
{
|
||||
int i,j,k;
|
||||
struct {
|
||||
|
|
@ -117,7 +117,7 @@ int r_asm_x86_pseudo(struct r_asm_t *a)
|
|||
nw++;
|
||||
}
|
||||
|
||||
r_asm_x86_aop(nw, wa, (char*)a->aux);
|
||||
r_asm_x86_replace(nw, wa, (char*)a->aux);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,11 @@ int r_asm_set_parser(struct r_asm_t *a,
|
|||
a->r_asm_parse = &r_asm_x86_pseudo;
|
||||
break;
|
||||
} else return R_FALSE;
|
||||
case R_ASM_PAR_AOP:
|
||||
if (a->arch == R_ASM_ARCH_X86) {
|
||||
a->r_asm_parse = &r_asm_x86_aop;
|
||||
break;
|
||||
} else return R_FALSE;
|
||||
case R_ASM_PAR_REALLOC:
|
||||
if (a->arch == R_ASM_ARCH_X86 && a->syntax == R_ASM_SYN_INTEL) {
|
||||
a->r_asm_parse = &r_asm_x86_realloc;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
LDFLAGS=-L../../util -lr_util -L../ -lr_asm
|
||||
LDFLAGS_BIN=${LDFLAGS} -lr_bin -L../../bin
|
||||
all: disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86
|
||||
all: disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86 aop_x86
|
||||
|
||||
disasm_x86:
|
||||
${CC} -g -I ../../include disasm_x86.c ${LDFLAGS} -o disasm_x86
|
||||
|
|
@ -29,5 +29,8 @@ rasm2:
|
|||
realloc_x86:
|
||||
${CC} -g -I ../../include realloc_x86.c ${LDFLAGS_BIN} -o realloc_x86
|
||||
|
||||
aop_x86:
|
||||
${CC} -g -I ../../include aop_x86.c ${LDFLAGS_BIN} -o aop_x86
|
||||
|
||||
clean:
|
||||
rm -f disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86
|
||||
rm -f disasm_x86 disasm_arm disasm_mips disasm_sparc disasm_ppc disasm_bf asm_x86 rasm2 realloc_x86 aop_x86
|
||||
|
|
|
|||
41
libr/asm/t/aop_x86.c
Normal file
41
libr/asm/t/aop_x86.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
struct r_asm_t a;
|
||||
struct r_anal_aop_t aop;
|
||||
u8 *buf = "\x74\x31"
|
||||
"\x74\x31"
|
||||
"\x74\x31"
|
||||
"\xc7\xc0\x04\x00\x00\x00";
|
||||
int ret = 0;
|
||||
u64 idx = 0, len = 12;
|
||||
|
||||
r_asm_init(&a);
|
||||
r_asm_set_arch(&a, R_ASM_ARCH_X86);
|
||||
r_asm_set_bits(&a, 32);
|
||||
r_asm_set_big_endian(&a, R_FALSE);
|
||||
r_asm_set_syntax(&a, R_ASM_SYN_INTEL);
|
||||
r_asm_set_parser(&a, R_ASM_PAR_AOP, NULL, &aop);
|
||||
|
||||
while (idx < len) {
|
||||
r_asm_set_pc(&a, 0x8048000 + idx);
|
||||
|
||||
ret = r_asm_disasm(&a, buf+idx, len-idx);
|
||||
printf("DISASM %s HEX %s\n", a.buf_asm, a.buf_hex);
|
||||
|
||||
r_asm_parse(&a);
|
||||
printf("AOP_JMP 0x%08llx\nAOP_FAIL 0x%08llx\n\n",
|
||||
aop.jump, aop.fail);
|
||||
|
||||
idx += ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
OBJ=hello.o
|
||||
BIN=hello
|
||||
LIBS=../*.o ../../io/*.o -lm
|
||||
BINDEPS=r_io r_hash
|
||||
LIBS=-lm
|
||||
|
||||
include ../../rules.mk
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include "r_types.h"
|
||||
|
||||
enum {
|
||||
R_ANAL_AOP_NULL = 0,
|
||||
R_ANAL_AOP_TYPE_NULL = 0,
|
||||
R_ANAL_AOP_TYPE_JMP, /* mandatory jump */
|
||||
R_ANAL_AOP_TYPE_UJMP, /* unknown jump (register or so) */
|
||||
R_ANAL_AOP_TYPE_CJMP, /* conditional jump */
|
||||
|
|
@ -57,8 +57,8 @@ enum {
|
|||
|
||||
enum {
|
||||
R_ANAL_STACK_NULL = 0,
|
||||
R_ANAL_STACK_NOP, /* sub $0xc, %esp */
|
||||
R_ANAL_STACK_INCSTACK, /* sub $0xc, %esp */
|
||||
R_ANAL_STACK_NOP,
|
||||
R_ANAL_STACK_INCSTACK,
|
||||
R_ANAL_STACK_LOCAL_GET,
|
||||
R_ANAL_STACK_LOCAL_SET,
|
||||
R_ANAL_STACK_ARG_GET,
|
||||
|
|
@ -78,9 +78,11 @@ struct r_anal_aop_t {
|
|||
u64 i_dst,i_src1,i_src2; /* inmediate arguments */
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct r_anal_t {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
/* anal.c */
|
||||
struct r_anal_t *r_anal_new();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ enum {
|
|||
enum {
|
||||
R_ASM_PAR_NULL = 0,
|
||||
R_ASM_PAR_PSEUDO,
|
||||
R_ASM_PAR_AOP,
|
||||
R_ASM_PAR_REALLOC
|
||||
};
|
||||
|
||||
|
|
@ -40,6 +41,8 @@ struct r_asm_t {
|
|||
int syntax;
|
||||
int parser;
|
||||
u64 pc;
|
||||
int inst_len;
|
||||
u8 buf[256];
|
||||
char buf_asm[256];
|
||||
char buf_hex[256];
|
||||
char buf_err[256];
|
||||
|
|
@ -70,6 +73,8 @@ int r_asm_x86_disasm(struct r_asm_t *a, u8 *buf, u64 len);
|
|||
int r_asm_x86_asm(struct r_asm_t *a, char *buf);
|
||||
/* arch/x86/pseudo.c */
|
||||
int r_asm_x86_pseudo(struct r_asm_t *a);
|
||||
/* arch/x86/aop.c */
|
||||
int r_asm_x86_aop(struct r_asm_t *a);
|
||||
/* arch/x86/realloc.c */
|
||||
struct r_asm_realloc_t {
|
||||
u64 offset;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
OBJ=hello.o
|
||||
BIN=hello
|
||||
LIBS=../*.o
|
||||
BINDEPS=r_syscall
|
||||
|
||||
include ../../rules.mk
|
||||
|
|
|
|||
Loading…
Reference in a new issue