summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-10-19 15:05:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-10-19 15:05:04 (GMT)
commit10deb6bbbeeaacfec577f5b24c5f821492af77f3 (patch)
tree9db0a1679c518f6a95cdb25e38c7a281b8ea30c1 /src/arch
parent43f740ee35b452980e8d190660896a535816dfc3 (diff)
Registered symbols found in the PLT.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@35 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/instruction-int.h22
-rw-r--r--src/arch/instruction.c2
-rw-r--r--src/arch/operand.c118
-rw-r--r--src/arch/operand.h3
-rw-r--r--src/arch/processor.c5
-rw-r--r--src/arch/x86/instruction.h4
-rw-r--r--src/arch/x86/op_add.c35
-rw-r--r--src/arch/x86/op_jump.c86
-rw-r--r--src/arch/x86/op_push.c6
-rw-r--r--src/arch/x86/opcodes.h9
-rw-r--r--src/arch/x86/operand.c26
-rw-r--r--src/arch/x86/processor.c18
12 files changed, 325 insertions, 9 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 72c7914..895c29f 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -40,11 +40,33 @@
#define DB_OPCODE 0x00
+
+/* Typage des instructions rencontrées */
+typedef enum _AsmInstrType
+{
+ AIT_OTHER, /* Instruction inintéressante */
+
+ AIT_DB, /* Instruction non décodée */
+
+ AIT_PUSH, /* Empilement de valeur */
+ AIT_POP, /* Dépilement de valeur */
+ AIT_JUMP, /* Saut à une adresse */
+
+ AIT_CALL /* Appel d'une fonction */
+
+} AsmInstrType;
+
+
+
/* Définition générique d'une instruction */
struct _asm_instr
{
uint8_t opcode;
+ uint64_t vaddress; /* Adresse virtuelle associée */
+
+ AsmInstrType type; /* Type d'instruction */
+
asm_operand **operands; /* Liste des opérandes */
size_t operands_count; /* Nbre. d'opérandes utilisées */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index e199dc5..ada3d58 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -53,6 +53,8 @@ asm_instr *create_db_instruction(const uint8_t *data, off_t *pos, off_t len)
result->opcode = DB_OPCODE;
+ result->type = AIT_DB;
+
/* TODO: check result */
result->operands = (asm_operand **)calloc(1, sizeof(asm_operand *));
result->operands[0] = (asm_operand *)calloc(1, sizeof(asm_operand));
diff --git a/src/arch/operand.c b/src/arch/operand.c
index 53e652c..fa43416 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -367,6 +367,124 @@ bool fill_relimm_operand(asm_operand *operand, AsmOperandSize size, const uint8_
/******************************************************************************
* *
+* Paramètres : operand = structure dont le contenu est à définir. *
+* size = taille de l'opérande souhaitée. *
+* ... = zone d'enregistrement prévue. *
+* *
+* Description : Récupère la valeur d'une opérande sur x bits. *
+* *
+* Retour : true si l'opération s'est effectuée avec succès, false sinon.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool get_imm_operand_value(asm_operand *operand, AsmOperandSize size, ...)
+{
+ bool result; /* Bilan à retourner */
+ va_list ap; /* Récupération d'argument */
+ uint8_t *val8; /* Valeur sur 8 bits */
+ uint16_t *val16; /* Valeur sur 16 bits */
+ uint32_t *val32; /* Valeur sur 32 bits */
+ uint64_t *val64; /* Valeur sur 64 bits */
+
+ result = true;
+
+ va_start(ap, size);
+
+ switch (size)
+ {
+ case AOS_8_BITS:
+ val8 = va_arg(ap, uint8_t *);
+ switch (operand->size)
+ {
+ case AOS_8_BITS:
+ *val8 = operand->value.val8;
+ break;
+ case AOS_16_BITS:
+ result = false;
+ break;
+ case AOS_32_BITS:
+ result = false;
+ break;
+ case AOS_64_BITS:
+ result = false;
+ break;
+ }
+ break;
+
+ case AOS_16_BITS:
+ val16 = va_arg(ap, uint16_t *);
+ switch (operand->size)
+ {
+ case AOS_8_BITS:
+ *val16 = operand->value.val8;
+ break;
+ case AOS_16_BITS:
+ *val16 = operand->value.val16;
+ break;
+ case AOS_32_BITS:
+ result = false;
+ break;
+ case AOS_64_BITS:
+ result = false;
+ break;
+ }
+ break;
+
+ case AOS_32_BITS:
+ val32 = va_arg(ap, uint32_t *);
+ switch (operand->size)
+ {
+ case AOS_8_BITS:
+ *val32 = operand->value.val8;
+ break;
+ case AOS_16_BITS:
+ *val32 = operand->value.val16;
+ break;
+ case AOS_32_BITS:
+ *val32 = operand->value.val32;
+ break;
+ case AOS_64_BITS:
+ result = false;
+ break;
+ }
+ break;
+
+ case AOS_64_BITS:
+ val64 = va_arg(ap, uint64_t *);
+ switch (operand->size)
+ {
+ case AOS_8_BITS:
+ *val64 = operand->value.val8;
+ break;
+ case AOS_16_BITS:
+ *val64 = operand->value.val16;
+ break;
+ case AOS_32_BITS:
+ *val64 = operand->value.val32;
+ break;
+ case AOS_64_BITS:
+ *val64 = operand->value.val64;
+ break;
+ }
+ break;
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ va_end(ap);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = instruction à traiter. *
* buffer = tampon de sortie mis à disposition. [OUT] *
* len = taille de ce tampon. *
diff --git a/src/arch/operand.h b/src/arch/operand.h
index a05f819..0a00d9f 100644
--- a/src/arch/operand.h
+++ b/src/arch/operand.h
@@ -76,6 +76,9 @@ bool fill_imm_operand_with_value(asm_operand *, AsmOperandSize, ...);
/* Crée une opérande contenant une valeur relative sur x bits. */
bool fill_relimm_operand(asm_operand *, AsmOperandSize, const uint8_t *, off_t *, off_t, uint64_t);
+/* Récupère la valeur d'une opérande sur x bits. */
+bool get_imm_operand_value(asm_operand *, AsmOperandSize, ...);
+
/* Traduit une opérande de valeur immédiate en texte. */
void print_imm_operand(const asm_operand *, char *, size_t, AsmSyntax);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 373222f..fc9f773 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -24,12 +24,14 @@
#include "processor.h"
+#include "instruction-int.h"
#include "processor-int.h"
+
/******************************************************************************
* *
* Paramètres : proc = architecture visée par la procédure. *
@@ -66,6 +68,9 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of
}
+ result->vaddress = offset;
+
+
return result;
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 8ef603f..baf911d 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -38,6 +38,8 @@ typedef struct _asm_x86_instr asm_x86_instr;
/* Enumération de tous les opcodes */
typedef enum _X86Opcodes
{
+ X86_OP_ADD_RM8_R8, /* add (0x00) */
+
X86_OP_SUB_R1632_RM1632, /* sub ([0x66] 0x29) */
X86_OP_XOR_RM8_R8, /* xor (0x30) */
@@ -145,12 +147,14 @@ typedef enum _X86Opcodes
X86_OP_INT, /* int (0xcd) */
X86_OP_CALL_REL1632, /* call ([0x66] 0xe8) */
+ X86_OP_JMP_REL1632, /* jmp ([0x66] 0xe9) */
X86_OP_JMP_8, /* jmp (0xeb) */
X86_OP_HLT, /* hlt (0xf4) */
X86_OP_CALL_RM1632, /* call ([0x66] 0xff 2) */
+ X86_OP_JMP_RM1632, /* jmp ([0x66] 0xff 4) */
X86_OP_PUSH_RM1632, /* push ([0x66] 0xff 6) */
X86_OP_COUNT
diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c
index 52b998f..f42c8f9 100644
--- a/src/arch/x86/op_add.c
+++ b/src/arch/x86/op_add.c
@@ -104,3 +104,38 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'add' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+{
+ asm_x86_instr *result; /* Instruction à retourner */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c
index b301b10..3739b24 100644
--- a/src/arch/x86/op_jump.c
+++ b/src/arch/x86/op_jump.c
@@ -54,6 +54,8 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -89,6 +91,8 @@ asm_x86_instr *x86_read_instr_jne_8(const uint8_t *data, off_t *pos, off_t len,
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -124,6 +128,8 @@ asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *data, off_t *pos, off_t len,
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -133,3 +139,83 @@ asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *data, off_t *pos, off_t len,
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'jmp' (grand saut relatif). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jmp_rel1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+{
+ asm_x86_instr *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, offset))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'jmp' (saut en mémoire). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jmp_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+{
+ asm_x86_instr *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_push.c b/src/arch/x86/op_push.c
index ce76919..f51bd6f 100644
--- a/src/arch/x86/op_push.c
+++ b/src/arch/x86/op_push.c
@@ -58,6 +58,8 @@ asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_IMM1632, oprsize))
{
free(result);
@@ -96,6 +98,8 @@ asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *data, off_t *pos, off_t
ASM_INSTRUCTION(result)->opcode = data[*pos];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x50))
{
free(result);
@@ -134,6 +138,8 @@ asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *data, off_t *pos, off_t
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize))
{
free(result);
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index cbadcf5..70d41b8 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -43,6 +43,9 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t
/* Décode une instruction de type 'add' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'add' (8 bits). */
+asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'and' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -82,6 +85,12 @@ asm_x86_instr *x86_read_instr_jne_8(const uint8_t *, off_t *, off_t, uint64_t, c
/* Décode une instruction de type 'jump' (petit saut). */
asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'jmp' (grand saut relatif). */
+asm_x86_instr *x86_read_instr_jmp_rel1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'jmp' (saut en mémoire). */
+asm_x86_instr *x86_read_instr_jmp_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'lea' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_lea(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index 375b0a5..e13c793 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -1300,7 +1300,8 @@ asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t base, const uint8_t
{
asm_x86_operand *result; /* Emplacement à retourner */
off_t init_pos; /* Position avant lecture */
- int8_t offset; /* Décallage à appliquer */
+ int32_t offset32; /* Décallage 32b à appliquer */
+ int16_t offset16; /* Décallage 16b à appliquer */
uint32_t address; /* Adresse finale visée */
result = create_new_x86_operand();
@@ -1308,13 +1309,28 @@ asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t base, const uint8_t
init_pos = *pos;
address = base;
- if (!read_imm_value(is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len, &offset))
+ if (is_reg32)
{
- free(result);
- return NULL;
+ if (!read_imm_value(AOS_32_BITS, data, pos, len, &offset32))
+ {
+ free(result);
+ return NULL;
+ }
+
+ address = base + (*pos - init_pos) + offset32;
+
}
+ else
+ {
+ if (!read_imm_value(AOS_16_BITS, data, pos, len, &offset16))
+ {
+ free(result);
+ return NULL;
+ }
- address = base + (*pos - init_pos) + offset;
+ address = base + (*pos - init_pos) + offset16;
+
+ }
if (!fill_imm_operand_with_value(ASM_OPERAND(result), AOS_32_BITS, &address))
{
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 0b81a8c..5694d9e 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -61,7 +61,7 @@ typedef struct _x86_opcode
do { \
target.prefix = _prefix; \
target.opcode = _opcode; \
- target.opt_prefix = true; \
+ target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = false; \
target.name = _name; \
target.read = _read; \
@@ -72,7 +72,7 @@ typedef struct _x86_opcode
target.prefix = _prefix; \
target.opcode = _opcode; \
target.op_ext = _ext << 3; \
- target.opt_prefix = true; \
+ target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = true; \
target.name = _name; \
target.read = _read; \
@@ -205,6 +205,8 @@ AsmOperandSize switch_x86_operand_size_if_needed(const asm_x86_processor *proc,
void x86_register_instructions(asm_x86_processor *proc)
{
+ register_opcode(proc->opcodes[X86_OP_ADD_RM8_R8], 0x00, 0x00, "add", x86_read_instr_add_rm8_r8);
+
register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632);
register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x00, 0x30, "xor", x86_read_instr_xor_rm8_with_r8);
@@ -314,12 +316,14 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_CALL_REL1632], 0x66, 0xe8, "call", x86_read_instr_call_rel1632);
+ register_opcode(proc->opcodes[X86_OP_JMP_REL1632], 0x66, 0xe9, "jmp", x86_read_instr_jmp_rel1632);
register_opcode(proc->opcodes[X86_OP_JMP_8], 0x00, 0xeb, "jmp", x86_read_instr_jmp_8);
register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", x86_read_instr_hlt);
register_opcode_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0x66, 0xff, 2, "call", x86_read_instr_call_rm1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_JMP_RM1632], 0x66, 0xff, 4, "jmp", x86_read_instr_jmp_rm1632);
register_opcode_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0x66, 0xff, 6, "push", x86_read_instr_push_rm1632);
@@ -367,6 +371,12 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
goto find_instr;
}
+ if (proc->opcodes[i].prefix == 0x00 && data[*pos] == proc->opcodes[i].opcode)
+ {
+ tmp = *pos + 1;
+ goto find_instr;
+ }
+
continue;
find_instr:
@@ -381,7 +391,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
else
{
*pos = old_pos;
- printf("err while decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode);
+ printf("err while x86 decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode);
}
break;
@@ -456,7 +466,7 @@ void x86_print_instruction(const asm_x86_processor *proc, const exe_format *form
/* Impression globale finale */
- if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE)
+ if (ASM_INSTRUCTION(instr)->type == AIT_DB)
snprintf(buffer, len, "db\t%s", opbuffer[0]);
else