diff options
| -rw-r--r-- | ChangeLog | 35 | ||||
| -rw-r--r-- | configure.ac | 1 | ||||
| -rw-r--r-- | src/arch/dalvik/Makefile.am | 8 | ||||
| -rw-r--r-- | src/arch/dalvik/instruction-def.h | 208 | ||||
| -rw-r--r-- | src/arch/dalvik/instruction-int.h | 52 | ||||
| -rw-r--r-- | src/arch/dalvik/instruction.c | 18 | ||||
| -rw-r--r-- | src/arch/dalvik/instruction.h | 171 | ||||
| -rw-r--r-- | src/arch/dalvik/processor.c | 83 | ||||
| -rw-r--r-- | src/arch/dalvik/pseudo/Makefile.am | 17 | ||||
| -rw-r--r-- | src/arch/dalvik/pseudo/fill.c | 214 | ||||
| -rw-r--r-- | src/arch/dalvik/pseudo/fill.h | 57 | ||||
| -rw-r--r-- | src/arch/dalvik/pseudo/switch.c | 217 | ||||
| -rw-r--r-- | src/arch/dalvik/pseudo/switch.h | 57 | ||||
| -rw-r--r-- | src/arch/dalvik/specins.c | 115 | ||||
| -rw-r--r-- | src/arch/dalvik/specins.h | 51 | ||||
| -rw-r--r-- | src/arch/instruction-int.h | 4 | ||||
| -rw-r--r-- | src/arch/instruction.c | 35 | 
17 files changed, 973 insertions, 370 deletions
| @@ -1,3 +1,38 @@ +11-12-23  Cyrille Bagard <nocbos@gmail.com> + +	* configure.ac: +	Add the new Makefile from the 'src/arch/dalvik/pseudo' directory to +	AC_CONFIG_FILES. + +	* src/arch/dalvik/instruction.c: +	* src/arch/dalvik/instruction-def.h: +	* src/arch/dalvik/instruction.h: +	* src/arch/dalvik/instruction-int.h: +	Reorganize the definition of Dalvik instructions. + +	* src/arch/dalvik/Makefile.am: +	Add the instruction-{def,int}.h files to libarchdalvik_la_SOURCES and +	pseudo/libarchdalvikpseudo.la to libarchdalvik_la_LIBADD. Remove all +	specins.[ch]-related things. + +	* src/arch/dalvik/processor.c: +	Decode Dalvik pseudo-instructions. + +	* src/arch/dalvik/pseudo/fill.c: +	* src/arch/dalvik/pseudo/fill.h: +	* src/arch/dalvik/pseudo/Makefile.am: +	* src/arch/dalvik/pseudo/switch.c: +	* src/arch/dalvik/pseudo/switch.h: +	New entries: decode pseudo-instructions properly. + +	* src/arch/dalvik/specins.c: +	* src/arch/dalvik/specins.h: +	Deleted entries. + +	* src/arch/instruction.c: +	* src/arch/instruction-int.h: +	Allow each instruction to provide its own printing method. +  11-12-09  Cyrille Bagard <nocbos@gmail.com>  	* src/configuration.c: diff --git a/configure.ac b/configure.ac index ad71854..f3679d6 100644 --- a/configure.ac +++ b/configure.ac @@ -251,6 +251,7 @@ AC_CONFIG_FILES([Makefile                   src/arch/arm/Makefile                   src/arch/dalvik/Makefile                   src/arch/dalvik/operands/Makefile +                 src/arch/dalvik/pseudo/Makefile                   src/arch/jvm/Makefile                   src/arch/mips/Makefile                   src/arch/x86/Makefile diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am index 6640180..18fb08d 100644 --- a/src/arch/dalvik/Makefile.am +++ b/src/arch/dalvik/Makefile.am @@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libarchdalvik.la  libarchdalvik_la_SOURCES =				\  	context.h context.c					\ +	instruction-def.h					\ +	instruction-int.h					\  	instruction.h instruction.c			\  	dop_aget.c							\  	dop_aput.c							\ @@ -43,11 +45,11 @@ libarchdalvik_la_SOURCES =				\  	operand.h operand.c					\  	processor.h processor.c				\  	register.h register.c				\ -	specins.h specins.c					\  	translate.h  libarchdalvik_la_LIBADD =				\ -	operands/libarchdalvikoperands.la +	operands/libarchdalvikoperands.la	\ +	pseudo/libarchdalvikpseudo.la  libarchdalvik_la_CFLAGS = $(AM_CFLAGS) @@ -59,4 +61,4 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = operands +SUBDIRS = operands pseudo diff --git a/src/arch/dalvik/instruction-def.h b/src/arch/dalvik/instruction-def.h new file mode 100644 index 0000000..48d7e96 --- /dev/null +++ b/src/arch/dalvik/instruction-def.h @@ -0,0 +1,208 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction-def.h - définition interne des identifiants d'instructions Dalvik + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_DALVIK_INSTRUCTION_DEF_H +#define _ARCH_DALVIK_INSTRUCTION_DEF_H + + + +/* Enumération de tous les opcodes */ +typedef enum _DalvikOpcodes +{ +    DOP_NOP,                                /* nop (0x00)                  */ +    DOP_MOVE,                               /* move (0x01)                 */ +    DOP_MOVE_FROM_16,                       /* move/from16 (0x02)          */ + +    DOP_MOVE_OBJECT,                        /* move-object (0x07)          */ + +    DOP_MOVE_RESULT,                        /* move-result (0x0a)          */ +    DOP_MOVE_RESULT_WIDE,                   /* move-result-wide (0x0b)     */ +    DOP_MOVE_RESULT_OBJECT,                 /* move-result-object (0x0c)   */ +    DOP_MOVE_EXCEPTION,                     /* move-exception (0x0d)       */ +    DOP_RETURN_VOID,                        /* return-void (0x0e)          */ +    DOP_RETURN,                             /* return (0x0f)               */ +    DOP_RETURN_WIDE,                        /* return-wide (0x10)          */ +    DOP_RETURN_OBJECT,                      /* return-object (0x11)        */ +    DOP_CONST_4,                            /* const/4 (0x12)              */ +    DOP_CONST_16,                           /* const/16 (0x13)             */ +    DOP_CONST,                              /* const (0x14)                */ +    DOP_CONST_HIGH16,                       /* const/high16 (0x15)         */ +    DOP_CONST_WIDE_16,                      /* const-wide/16 (0x16)        */ + +    DOP_CONST_WIDE,                         /* const-wide (0x18)           */ + +    DOP_CONST_STRING,                       /* const-string (0x1a)         */ + + +    DOP_CHECK_CAST,                         /* check-cast (0x1f)           */ + +    DOP_ARRAY_LENGTH,                       /* array-length (0x21)         */ +    DOP_NEW_INSTANCE,                       /* new-instance (0x22)         */ +    DOP_NEW_ARRAY,                          /* new-array (0x23)            */ + +    DOP_FILL_ARRAY_DATA,                    /* fill-array-data (0x26)      */ + +    DOP_GOTO,                               /* goto (0x28)                 */ +    DOP_GOTO_16,                            /* goto/16 (0x29)              */ +    DOP_GOTO_32,                            /* goto/32 (0x2a)              */ + + +    DOP_CMPL_FLOAT,                         /* cmp-long (0x2d)             */ +    DOP_CMPG_FLOAT,                         /* cmpg-float (0x2e)           */ +    DOP_CMPL_DOUBLE,                        /* cmpl-double (0x2f)          */ +    DOP_CMPG_DOUBLE,                        /* cmpg-double (0x30)          */ +    DOP_CMP_LONG,                           /* cmp-long (0x31)             */ +    DOP_IF_EQ,                              /* if-eq (0x32)                */ +    DOP_IF_NE,                              /* if-ne (0x33)                */ +    DOP_IF_LT,                              /* if-lt (0x34)                */ +    DOP_IF_GE,                              /* if-ge (0x35)                */ +    DOP_IF_GT,                              /* if-gt (0x36)                */ +    DOP_IF_LE,                              /* if-le (0x37)                */ +    DOP_IF_EQZ,                             /* if-eqz (0x38)               */ +    DOP_IF_NEZ,                             /* if-nez (0x39)               */ +    DOP_IF_LTZ,                             /* if-ltz (0x3a)               */ +    DOP_IF_GEZ,                             /* if-gez (0x3b)               */ +    DOP_IF_GTZ,                             /* if-gtz (0x3c)               */ +    DOP_IF_LEZ,                             /* if-lez (0x3d)               */ + + + +    DOP_AGET,                               /* aget (0x44)                 */ +    DOP_AGET_WIDE,                          /* aget-wide (0x45)            */ +    DOP_AGET_OBJECT,                        /* aget-object (0x46)          */ +    DOP_AGET_BOOLEAN,                       /* aget-boolean (0x47)         */ +    DOP_AGET_BYTE,                          /* aget-byte (0x48)            */ +    DOP_AGET_CHAR,                          /* aget-char (0x49)            */ +    DOP_AGET_SHORT,                         /* aget-short (0x4a)           */ +    DOP_APUT,                               /* aput (0x4b)                 */ +    DOP_APUT_WIDE,                          /* aput-wide (0x4c)            */ +    DOP_APUT_OBJECT,                        /* aput-object (0x4d)          */ +    DOP_APUT_BOOLEAN,                       /* aput-boolean (0x4e)         */ +    DOP_APUT_BYTE,                          /* aput-byte (0x4f)            */ +    DOP_APUT_CHAR,                          /* aput-char (0x50)            */ +    DOP_APUT_SHORT,                         /* aput-short (0x51)           */ +    DOP_IGET,                               /* iget (0x52)                 */ +    DOP_IGET_WIDE,                          /* iget-wide (0x53)            */ +    DOP_IGET_OBJECT,                        /* iget-object (0x54)          */ +    DOP_IGET_BOOLEAN,                       /* iget-boolean (0x55)         */ +    DOP_IGET_BYTE,                          /* iget-byte (0x56)            */ +    DOP_IGET_CHAR,                          /* iget-char (0x57)            */ +    DOP_IGET_SHORT,                         /* iget-short (0x58)           */ +    DOP_IPUT,                               /* iput (0x59)                 */ +    DOP_IPUT_WIDE,                          /* iput-wide (0x5a)            */ +    DOP_IPUT_OBJECT,                        /* iput-object (0x5b)          */ +    DOP_IPUT_BOOLEAN,                       /* iput-boolean (0x5c)         */ +    DOP_IPUT_BYTE,                          /* iput-byte (0x5d)            */ +    DOP_IPUT_CHAR,                          /* iput-char (0x5e)            */ +    DOP_IPUT_SHORT,                         /* iput-short (0x5f)           */ +    DOP_SGET,                               /* sget (0x60)                 */ +    DOP_SGET_WIDE,                          /* sget-wide (0x61)            */ +    DOP_SGET_OBJECT,                        /* sget-object (0x62)          */ +    DOP_SGET_BOOLEAN,                       /* sget-boolean (0x63)         */ +    DOP_SGET_BYTE,                          /* sget-byte (0x64)            */ +    DOP_SGET_CHAR,                          /* sget-char (0x65)            */ +    DOP_SGET_SHORT,                         /* sget-short (0x66)           */ +    DOP_SPUT,                               /* sput (0x67)                 */ +    DOP_SPUT_WIDE,                          /* sput-wide (0x68)            */ +    DOP_SPUT_OBJECT,                        /* sput-object (0x69)          */ +    DOP_SPUT_BOOLEAN,                       /* sput-boolean (0x6a)         */ +    DOP_SPUT_BYTE,                          /* sput-byte (0x6b)            */ +    DOP_SPUT_CHAR,                          /* sput-char (0x6c)            */ +    DOP_SPUT_SHORT,                         /* sput-short (0x6d)           */ +    DOP_INVOKE_VIRTUAL,                     /* invoke-virtual (0x6e)       */ +    DOP_INVOKE_SUPER,                       /* invoke-super (0x6f)         */ +    DOP_INVOKE_DIRECT,                      /* invoke-direct (0x70)        */ +    DOP_INVOKE_STATIC,                      /* invoke-static (0x71)        */ +    DOP_INVOKE_INTERFACE,                   /* invoke-interface (0x72)     */ + + + +    DOP_TO_INT_LONG,                        /* int-to-long (0x81)          */ +    DOP_TO_INT_FLOAT,                       /* int-to-float (0x82)         */ +    DOP_TO_INT_DOUBLE,                      /* int-to-double (0x83)        */ +    DOP_TO_LONG_INT,                        /* long-to-int (0x84)          */ +    DOP_TO_LONG_FLOAT,                      /* long-to-float (0x85)        */ +    DOP_TO_LONG_DOUBLE,                     /* long-to-double (0x86)       */ +    DOP_TO_FLOAT_INT,                       /* float-to-int (0x87)         */ +    DOP_TO_FLOAT_LONG,                      /* float-to-long (0x88)        */ +    DOP_TO_FLOAT_DOUBLE,                    /* float-to-double (0x89)      */ +    DOP_TO_DOUBLE_INT,                      /* double-to-int (0x8a)        */ +    DOP_TO_DOUBLE_LONG,                     /* double-to-long (0x8b)       */ +    DOP_TO_DOUBLE_FLOAT,                    /* double-to-float (0x8c)      */ +    DOP_TO_INT_BYTE,                        /* int-to-byte (0x8d)          */ +    DOP_TO_INT_CHAR,                        /* int-to-char (0x8e)          */ +    DOP_TO_INT_SHORT,                       /* int-to-short (0x8f)         */ +    DOP_ADD_INT,                            /* add-int (0x90)              */ +    DOP_SUB_INT,                            /* sub-int (0x91)              */ +    DOP_MUL_INT,                            /* mul-int (0x92)              */ +    DOP_DIV_INT,                            /* div-int (0x93)              */ +    DOP_REM_INT,                            /* rem-int (0x94)              */ +    DOP_AND_INT,                            /* and-int (0x95)              */ +    DOP_OR_INT,                             /* or-int (0x96)               */ +    DOP_XOR_INT,                            /* xor-int (0x97)              */ + +    DOP_ADD_INT_2ADDR,                      /* add-int/2addr (0xb0)        */ + +    DOP_MUL_INT_2ADDR,                      /* mul-int/2addr (0xb2)        */ +    DOP_DIV_INT_2ADDR,                      /* div-int/2addr (0xb3)        */ +    DOP_REM_INT_2ADDR,                      /* rem-int/2addr (0xb4)        */ +    DOP_AND_INT_2ADDR,                      /* and-int/2addr (0xb5)        */ +    DOP_OR_INT_2ADDR,                       /* or-int/2addr (0xb6)         */ +    DOP_XOR_INT_2ADDR,                      /* xor-int/2addr (0xb7)        */ + +    DOP_MUL_DOUBLE_2ADDR,                   /* mul-double/2addr (0xcd)     */ + +    DOP_ADD_INT_LIT16,                      /* add-int/lit16 (0xd0)        */ +    DOP_RSUB_INT,                           /* rsub-int (0xd1)             */ +    DOP_MUL_INT_LIT16,                      /* mul-int/lit16 (0xd2)        */ +    DOP_DIV_INT_LIT16,                      /* div-int/lit16 (0xd3)        */ +    DOP_REM_INT_LIT16,                      /* rem-int/lit16 (0xd4)        */ +    DOP_AND_INT_LIT16,                      /* and-int/lit16 (0xd5)        */ +    DOP_OR_INT_LIT16,                       /* or-int/lit16 (0xd6)         */ +    DOP_XOR_INT_LIT16,                      /* xor-int/lit16 (0xd7)        */ +    DOP_ADD_INT_LIT8,                       /* add-int/lit8 (0xd8)         */ +    DOP_RSUB_INT_LIT8,                      /* rsub-int/lit8 (0xd9)        */ +    DOP_MUL_INT_LIT8,                       /* mul-int/lit8 (0xda)         */ +    DOP_DIV_INT_LIT8,                       /* div-int/lit8 (0xdb)         */ +    DOP_REM_INT_LIT8,                       /* rem-int/lit8 (0xdc)         */ +    DOP_AND_INT_LIT8,                       /* and-int/lit8 (0xdd)         */ +    DOP_OR_INT_LIT8,                        /* or-int/lit8 (0xde)          */ +    DOP_XOR_INT_LIT8,                       /* xor-int/lit8 (0xdf)         */ + +    DOP_COUNT + +} DalvikOpcodes; + + +/* Enumération de tous les pseudo-opcodes */ +typedef enum _DalvikPseudoOpcodes +{ +    DPO_PACKED_SWITCH   = 0x0100,           /* Switch aux clefs compactes  */ +    DPO_SPARSE_SWITCH   = 0x0200,           /* Switch aux clefs éclatées   */ +    DPO_FILL_ARRAY_DATA = 0x0300            /* Contenu de tableau          */ + +} DalvikPseudoOpcodes; + + + +#endif  /* _ARCH_DALVIK_INSTRUCTION_DEF_H */ diff --git a/src/arch/dalvik/instruction-int.h b/src/arch/dalvik/instruction-int.h new file mode 100644 index 0000000..9166c0c --- /dev/null +++ b/src/arch/dalvik/instruction-int.h @@ -0,0 +1,52 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction-int.h - prototypes pour la définition générique interne des instructions Dalvik + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_DALVIK_INSTRUCTION_INT_H +#define _ARCH_DALVIK_INSTRUCTION_INT_H + + +#include "instruction-def.h" +#include "../instruction-int.h" + + + +/* Définition générique d'une instruction d'architecture Dalvik (instance) */ +struct _GDalvikInstruction +{ +    GArchInstruction parent;                /* A laisser en premier        */ + +    DalvikOpcodes type;                     /* Position dans la liste      */ +    DalvikPseudoOpcodes ptype;              /* Position dans la liste #2   */ + +}; + +/* Définition générique d'une instruction d'architecture Dalvik (classe) */ +struct _GDalvikInstructionClass +{ +    GArchInstructionClass parent;           /* A laisser en premier        */ + +}; + + + +#endif  /* _ARCH_DALVIK_INSTRUCTION_INT_H */ diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index 4595193..0d68a83 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -24,28 +24,12 @@  #include "instruction.h" +#include "instruction-int.h"  #include "translate.h"  #include "../instruction-int.h" -/* Définition générique d'une instruction d'architecture Dalvik (instance) */ -struct _GDalvikInstruction -{ -    GArchInstruction parent;                /* A laisser en premier        */ - -    DalvikOpcodes type;                     /* Position dans la liste      */ - -}; - -/* Définition générique d'une instruction d'architecture Dalvik (classe) */ -struct _GDalvikInstructionClass -{ -    GArchInstructionClass parent;           /* A laisser en premier        */ - -}; - -  /* Initialise la classe des instructions pour Dalvik. */  static void g_dalvik_instruction_class_init(GDalvikInstructionClass *); diff --git a/src/arch/dalvik/instruction.h b/src/arch/dalvik/instruction.h index c359c66..0caee00 100644 --- a/src/arch/dalvik/instruction.h +++ b/src/arch/dalvik/instruction.h @@ -25,178 +25,11 @@  #define _ARCH_DALVIK_INSTRUCTION_H +#include "instruction-def.h"  #include "../instruction.h" -/* Enumération de tous les opcodes */ -typedef enum _DalvikOpcodes -{ -    DOP_NOP,                                /* nop (0x00)                  */ -    DOP_MOVE,                               /* move (0x01)                 */ -    DOP_MOVE_FROM_16,                       /* move/from16 (0x02)          */ - -    DOP_MOVE_OBJECT,                        /* move-object (0x07)          */ - -    DOP_MOVE_RESULT,                        /* move-result (0x0a)          */ -    DOP_MOVE_RESULT_WIDE,                   /* move-result-wide (0x0b)     */ -    DOP_MOVE_RESULT_OBJECT,                 /* move-result-object (0x0c)   */ -    DOP_MOVE_EXCEPTION,                     /* move-exception (0x0d)       */ -    DOP_RETURN_VOID,                        /* return-void (0x0e)          */ -    DOP_RETURN,                             /* return (0x0f)               */ -    DOP_RETURN_WIDE,                        /* return-wide (0x10)          */ -    DOP_RETURN_OBJECT,                      /* return-object (0x11)        */ -    DOP_CONST_4,                            /* const/4 (0x12)              */ -    DOP_CONST_16,                           /* const/16 (0x13)             */ -    DOP_CONST,                              /* const (0x14)                */ -    DOP_CONST_HIGH16,                       /* const/high16 (0x15)         */ -    DOP_CONST_WIDE_16,                      /* const-wide/16 (0x16)        */ - -    DOP_CONST_WIDE,                         /* const-wide (0x18)           */ - -    DOP_CONST_STRING,                       /* const-string (0x1a)         */ - - -    DOP_CHECK_CAST,                         /* check-cast (0x1f)           */ - -    DOP_ARRAY_LENGTH,                       /* array-length (0x21)         */ -    DOP_NEW_INSTANCE,                       /* new-instance (0x22)         */ -    DOP_NEW_ARRAY,                          /* new-array (0x23)            */ - -    DOP_FILL_ARRAY_DATA,                    /* fill-array-data (0x26)      */ - -    DOP_GOTO,                               /* goto (0x28)                 */ -    DOP_GOTO_16,                            /* goto/16 (0x29)              */ -    DOP_GOTO_32,                            /* goto/32 (0x2a)              */ - - -    DOP_CMPL_FLOAT,                         /* cmp-long (0x2d)             */ -    DOP_CMPG_FLOAT,                         /* cmpg-float (0x2e)           */ -    DOP_CMPL_DOUBLE,                        /* cmpl-double (0x2f)          */ -    DOP_CMPG_DOUBLE,                        /* cmpg-double (0x30)          */ -    DOP_CMP_LONG,                           /* cmp-long (0x31)             */ -    DOP_IF_EQ,                              /* if-eq (0x32)                */ -    DOP_IF_NE,                              /* if-ne (0x33)                */ -    DOP_IF_LT,                              /* if-lt (0x34)                */ -    DOP_IF_GE,                              /* if-ge (0x35)                */ -    DOP_IF_GT,                              /* if-gt (0x36)                */ -    DOP_IF_LE,                              /* if-le (0x37)                */ -    DOP_IF_EQZ,                             /* if-eqz (0x38)               */ -    DOP_IF_NEZ,                             /* if-nez (0x39)               */ -    DOP_IF_LTZ,                             /* if-ltz (0x3a)               */ -    DOP_IF_GEZ,                             /* if-gez (0x3b)               */ -    DOP_IF_GTZ,                             /* if-gtz (0x3c)               */ -    DOP_IF_LEZ,                             /* if-lez (0x3d)               */ - - - -    DOP_AGET,                               /* aget (0x44)                 */ -    DOP_AGET_WIDE,                          /* aget-wide (0x45)            */ -    DOP_AGET_OBJECT,                        /* aget-object (0x46)          */ -    DOP_AGET_BOOLEAN,                       /* aget-boolean (0x47)         */ -    DOP_AGET_BYTE,                          /* aget-byte (0x48)            */ -    DOP_AGET_CHAR,                          /* aget-char (0x49)            */ -    DOP_AGET_SHORT,                         /* aget-short (0x4a)           */ -    DOP_APUT,                               /* aput (0x4b)                 */ -    DOP_APUT_WIDE,                          /* aput-wide (0x4c)            */ -    DOP_APUT_OBJECT,                        /* aput-object (0x4d)          */ -    DOP_APUT_BOOLEAN,                       /* aput-boolean (0x4e)         */ -    DOP_APUT_BYTE,                          /* aput-byte (0x4f)            */ -    DOP_APUT_CHAR,                          /* aput-char (0x50)            */ -    DOP_APUT_SHORT,                         /* aput-short (0x51)           */ -    DOP_IGET,                               /* iget (0x52)                 */ -    DOP_IGET_WIDE,                          /* iget-wide (0x53)            */ -    DOP_IGET_OBJECT,                        /* iget-object (0x54)          */ -    DOP_IGET_BOOLEAN,                       /* iget-boolean (0x55)         */ -    DOP_IGET_BYTE,                          /* iget-byte (0x56)            */ -    DOP_IGET_CHAR,                          /* iget-char (0x57)            */ -    DOP_IGET_SHORT,                         /* iget-short (0x58)           */ -    DOP_IPUT,                               /* iput (0x59)                 */ -    DOP_IPUT_WIDE,                          /* iput-wide (0x5a)            */ -    DOP_IPUT_OBJECT,                        /* iput-object (0x5b)          */ -    DOP_IPUT_BOOLEAN,                       /* iput-boolean (0x5c)         */ -    DOP_IPUT_BYTE,                          /* iput-byte (0x5d)            */ -    DOP_IPUT_CHAR,                          /* iput-char (0x5e)            */ -    DOP_IPUT_SHORT,                         /* iput-short (0x5f)           */ -    DOP_SGET,                               /* sget (0x60)                 */ -    DOP_SGET_WIDE,                          /* sget-wide (0x61)            */ -    DOP_SGET_OBJECT,                        /* sget-object (0x62)          */ -    DOP_SGET_BOOLEAN,                       /* sget-boolean (0x63)         */ -    DOP_SGET_BYTE,                          /* sget-byte (0x64)            */ -    DOP_SGET_CHAR,                          /* sget-char (0x65)            */ -    DOP_SGET_SHORT,                         /* sget-short (0x66)           */ -    DOP_SPUT,                               /* sput (0x67)                 */ -    DOP_SPUT_WIDE,                          /* sput-wide (0x68)            */ -    DOP_SPUT_OBJECT,                        /* sput-object (0x69)          */ -    DOP_SPUT_BOOLEAN,                       /* sput-boolean (0x6a)         */ -    DOP_SPUT_BYTE,                          /* sput-byte (0x6b)            */ -    DOP_SPUT_CHAR,                          /* sput-char (0x6c)            */ -    DOP_SPUT_SHORT,                         /* sput-short (0x6d)           */ -    DOP_INVOKE_VIRTUAL,                     /* invoke-virtual (0x6e)       */ -    DOP_INVOKE_SUPER,                       /* invoke-super (0x6f)         */ -    DOP_INVOKE_DIRECT,                      /* invoke-direct (0x70)        */ -    DOP_INVOKE_STATIC,                      /* invoke-static (0x71)        */ -    DOP_INVOKE_INTERFACE,                   /* invoke-interface (0x72)     */ - - - -    DOP_TO_INT_LONG,                        /* int-to-long (0x81)          */ -    DOP_TO_INT_FLOAT,                       /* int-to-float (0x82)         */ -    DOP_TO_INT_DOUBLE,                      /* int-to-double (0x83)        */ -    DOP_TO_LONG_INT,                        /* long-to-int (0x84)          */ -    DOP_TO_LONG_FLOAT,                      /* long-to-float (0x85)        */ -    DOP_TO_LONG_DOUBLE,                     /* long-to-double (0x86)       */ -    DOP_TO_FLOAT_INT,                       /* float-to-int (0x87)         */ -    DOP_TO_FLOAT_LONG,                      /* float-to-long (0x88)        */ -    DOP_TO_FLOAT_DOUBLE,                    /* float-to-double (0x89)      */ -    DOP_TO_DOUBLE_INT,                      /* double-to-int (0x8a)        */ -    DOP_TO_DOUBLE_LONG,                     /* double-to-long (0x8b)       */ -    DOP_TO_DOUBLE_FLOAT,                    /* double-to-float (0x8c)      */ -    DOP_TO_INT_BYTE,                        /* int-to-byte (0x8d)          */ -    DOP_TO_INT_CHAR,                        /* int-to-char (0x8e)          */ -    DOP_TO_INT_SHORT,                       /* int-to-short (0x8f)         */ -    DOP_ADD_INT,                            /* add-int (0x90)              */ -    DOP_SUB_INT,                            /* sub-int (0x91)              */ -    DOP_MUL_INT,                            /* mul-int (0x92)              */ -    DOP_DIV_INT,                            /* div-int (0x93)              */ -    DOP_REM_INT,                            /* rem-int (0x94)              */ -    DOP_AND_INT,                            /* and-int (0x95)              */ -    DOP_OR_INT,                             /* or-int (0x96)               */ -    DOP_XOR_INT,                            /* xor-int (0x97)              */ - -    DOP_ADD_INT_2ADDR,                      /* add-int/2addr (0xb0)        */ - -    DOP_MUL_INT_2ADDR,                      /* mul-int/2addr (0xb2)        */ -    DOP_DIV_INT_2ADDR,                      /* div-int/2addr (0xb3)        */ -    DOP_REM_INT_2ADDR,                      /* rem-int/2addr (0xb4)        */ -    DOP_AND_INT_2ADDR,                      /* and-int/2addr (0xb5)        */ -    DOP_OR_INT_2ADDR,                       /* or-int/2addr (0xb6)         */ -    DOP_XOR_INT_2ADDR,                      /* xor-int/2addr (0xb7)        */ - -    DOP_MUL_DOUBLE_2ADDR,                   /* mul-double/2addr (0xcd)     */ - -    DOP_ADD_INT_LIT16,                      /* add-int/lit16 (0xd0)        */ -    DOP_RSUB_INT,                           /* rsub-int (0xd1)             */ -    DOP_MUL_INT_LIT16,                      /* mul-int/lit16 (0xd2)        */ -    DOP_DIV_INT_LIT16,                      /* div-int/lit16 (0xd3)        */ -    DOP_REM_INT_LIT16,                      /* rem-int/lit16 (0xd4)        */ -    DOP_AND_INT_LIT16,                      /* and-int/lit16 (0xd5)        */ -    DOP_OR_INT_LIT16,                       /* or-int/lit16 (0xd6)         */ -    DOP_XOR_INT_LIT16,                      /* xor-int/lit16 (0xd7)        */ -    DOP_ADD_INT_LIT8,                       /* add-int/lit8 (0xd8)         */ -    DOP_RSUB_INT_LIT8,                      /* rsub-int/lit8 (0xd9)        */ -    DOP_MUL_INT_LIT8,                       /* mul-int/lit8 (0xda)         */ -    DOP_DIV_INT_LIT8,                       /* div-int/lit8 (0xdb)         */ -    DOP_REM_INT_LIT8,                       /* rem-int/lit8 (0xdc)         */ -    DOP_AND_INT_LIT8,                       /* and-int/lit8 (0xdd)         */ -    DOP_OR_INT_LIT8,                        /* or-int/lit8 (0xde)          */ -    DOP_XOR_INT_LIT8,                       /* xor-int/lit8 (0xdf)         */ - -    DOP_COUNT - -} DalvikOpcodes; - -  #define G_TYPE_DALVIK_INSTRUCTION                 g_dalvik_instruction_get_type()  #define G_DALVIK_INSTRUCTION(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_instruction_get_type(), GDalvikInstruction))  #define G_IS_DALVIK_INSTRUCTION(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_instruction_get_type())) @@ -217,7 +50,7 @@ GType g_dalvik_instruction_get_type(void);  GArchInstruction *g_dalvik_instruction_new(DalvikOpcodes);  /* Indique l'opcode associé à une instruction Dalvik. */ -DalvikOpcodes g_dalvik_instruction_get_opcode(const GDalvikInstruction *); +DalvikOpcodes g_dalvik_instruction_get_opcode(const struct _GDalvikInstruction *); diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c index 2f56f87..7925c55 100644 --- a/src/arch/dalvik/processor.c +++ b/src/arch/dalvik/processor.c @@ -27,7 +27,8 @@  #include "context.h"  #include "instruction.h"  #include "opcodes.h" -#include "specins.h" +#include "pseudo/fill.h" +#include "pseudo/switch.h"  #include "../processor-int.h" @@ -57,6 +58,9 @@ static void g_dalvik_processor_init(GDalvikProcessor *);  /* Fournit un contexte pour l'exécution du processeur Dalvik. */  static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *); +/* Décode une pseudo-instruction dans un flux de données. */ +static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *, const bin_t *, off_t *, off_t, vmpa_t); +  /* Décode une instruction dans un flux de données. */  static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *, GDalvikContext *, const bin_t *, off_t *, off_t, vmpa_t); @@ -157,6 +161,58 @@ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *pr  /******************************************************************************  *                                                                             *  *  Paramètres  : proc = architecture visée par la procédure.                  * +*                data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                                                                             * +*  Description : Décode une pseudo-instruction dans un flux de données.       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL si aucune trouvée.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr) +{ +    GArchInstruction *result;               /* Instruction à renvoyer      */ +    off_t tmp;                              /* Position modifiable         */ +    uint16_t ident;                         /* Valeur lue dans le code     */ + +    /* Vérification astucieuse et rapide...*/ +    if (data[*pos] != 0x00 /* DOP_NOP */) return NULL;  + +    tmp = *pos; + +    if (!read_u16(&ident, data, &tmp, len, SRE_LITTLE)) +        return NULL; + +    switch (ident) +    { +        case DPO_PACKED_SWITCH: +        case DPO_SPARSE_SWITCH: +            result = g_dalvik_switch_instr_new(data, pos, len, addr, proc); +            break; + +        case DPO_FILL_ARRAY_DATA: +            result = g_dalvik_fill_instr_new(data, pos, len, addr, proc); +            break; + +        default: +            result = NULL; +            break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture visée par la procédure.                  *  *                ctx  = contexte lié à l'exécution du processeur.             *  *                data = flux de données à analyser.                           *  *                pos  = position courante dans ce flux. [OUT]                 * @@ -341,22 +397,21 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc      }; -    /* Continuité d'une zone spéciale... */ -    if (g_dalvik_context_have_to_skip(ctx, addr)) -        return SKIPPED_INSTR; - -    /* Début d'une nouvelle zone spéciale... */ -    if (g_dalvik_guess_special_instruction(ctx, data, *pos, len, addr)) -        return SKIPPED_INSTR; - -    /* Ou instruction classique */ +    /* Pseudo-instruction... */ +    result = g_dalvik_guess_pseudo_instruction(proc, data, pos, len, addr); -    id = dalvik_guess_next_instruction(data, *pos, len); +    /* ... ou instruction classique */ +    if (result == NULL) +    { +        id = dalvik_guess_next_instruction(data, *pos, len); -    if (id != DOP_COUNT) (*pos)++; +        if (id != DOP_COUNT) +        { +            (*pos)++; +            result = decodings[id](data, pos, len, addr, proc); +        } -    if (id == DOP_COUNT) result = NULL; -    else result = decodings[id](data, pos, len, addr, proc); +    }      return result; diff --git a/src/arch/dalvik/pseudo/Makefile.am b/src/arch/dalvik/pseudo/Makefile.am new file mode 100644 index 0000000..05e361f --- /dev/null +++ b/src/arch/dalvik/pseudo/Makefile.am @@ -0,0 +1,17 @@ + +noinst_LTLIBRARIES = libarchdalvikpseudo.la + +libarchdalvikpseudo_la_SOURCES =		\ +	fill.h fill.c						\ +	switch.h switch.c + +libarchdalvikpseudo_la_LIBADD =  + +libarchdalvikpseudo_la_CFLAGS = $(AM_CFLAGS) + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/arch/dalvik/pseudo/fill.c b/src/arch/dalvik/pseudo/fill.c new file mode 100644 index 0000000..9573000 --- /dev/null +++ b/src/arch/dalvik/pseudo/fill.c @@ -0,0 +1,214 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * fill.c - prise en charge de l'instruction spéciale fill-array-data + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "fill.h" + + +#include <string.h>  + + +#include "../instruction-int.h" + + + +/* Définition générique d'une instruction d'architecture Dalvik (instance) */ +struct _GDalvikFillInstr +{ +    GDalvikInstruction parent;              /* A laisser en premier        */ + +    uint16_t array_width;                   /* Taille des éléments         */ +    uint32_t array_size;                    /* Taille du tableau           */ + +}; + +/* Définition générique d'une instruction d'architecture Dalvik (classe) */ +struct _GDalvikFillInstrClass +{ +    GDalvikInstructionClass parent;         /* A laisser en premier        */ + +}; + + + +/* Initialise la classe générique des instructions. */ +static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *); + +/* Initialise une instance d'opérande d'architecture. */ +static void g_dalvik_fill_instr_init(GDalvikFillInstr *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_fill_instr_print(const GDalvikFillInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); + + + +/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */ +G_DEFINE_TYPE(GDalvikFillInstr, g_dalvik_fill_instr, G_TYPE_DALVIK_INSTRUCTION); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe générique des instructions.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instance à initialiser.                              * +*                                                                             * +*  Description : Initialise une instance d'instruction d'architecture.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_fill_instr_init(GDalvikFillInstr *instr) +{ +    GArchInstruction *parent;               /* Instance parente            */ + +    parent = G_ARCH_INSTRUCTION(instr); + +    parent->print = (print_instruction_fc)g_dalvik_fill_instr_print; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             * +*  Description : Crée une pesudo-instruction Dalvik de remplissage.           * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_dalvik_fill_instr_new(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ +    GDalvikFillInstr *result;               /* Structure à retourner       */ +    uint16_t ident;                         /* Valeur lue dans le code     */ + +    result = g_object_new(G_TYPE_DALVIK_FILL_INSTR, NULL); + +    if (!read_u16(&ident, data, pos, len, SRE_LITTLE)) +        goto gdfin_bad; + +    G_DALVIK_INSTRUCTION(result)->ptype = DPO_FILL_ARRAY_DATA; + +    if (!read_u16(&result->array_width, data, pos, len, SRE_LITTLE)) +        goto gdfin_bad; +    if (!read_u32(&result->array_size, data, pos, len, SRE_LITTLE)) +        goto gdfin_bad; + +    *pos += result->array_width * result->array_size; + +    return G_ARCH_INSTRUCTION(result); + + gdfin_bad: + +    g_object_unref(result); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr  = instruction d'assemblage à représenter.             * +*                buffer = espace où placer ledit contenu.                     * +*                syntax = type de représentation demandée.                    * +*                                                                             * +*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_fill_instr_print(const GDalvikFillInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +{ +    GArchInstruction *base;                 /* Version basique de l'objet  */ +    GBufferLine *line;                      /* Ligne de destination        */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */ +    char *bin_code;                         /* Tampon du code binaire      */ +    off_t i;                                /* Boucle de parcours          */ +    const char *key;                        /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ + +    base = G_ARCH_INSTRUCTION(instr); + +    line = g_code_buffer_append_new_line(buffer); + +    /* Adresse virtuelle ou physique */ + +    len = vmpa_to_string(base->address, msize, address); + +    g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW); + +    /* Code brut */ + +    bin_code = (char *)calloc(3 * 3 + 3, sizeof(char)); + +    for (i = 0; i < 3; i++) +    { +        if ((i + 1) < 3) +            snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]); +        else +            snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]); +    } + +    g_buffer_line_insert_text(line, BLC_BINARY, +                              bin_code, 3 * 3 + 2, RTT_RAW_CODE); + +    free(bin_code); + +    /* Instruction proprement dite */ + +    key = "<fill-array>"; +    klen = strlen(key); + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + +} diff --git a/src/arch/dalvik/pseudo/fill.h b/src/arch/dalvik/pseudo/fill.h new file mode 100644 index 0000000..058e67b --- /dev/null +++ b/src/arch/dalvik/pseudo/fill.h @@ -0,0 +1,57 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * fill.h - prototypes pour la prise en charge de l'instruction spéciale fill-array-data + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_DALVIK_PSEUDO_FILL_H +#define _ARCH_DALVIK_PSEUDO_FILL_H + + +#include "../instruction.h" +#include "../processor.h" + + +#include <glib-object.h> + + + +#define G_TYPE_DALVIK_FILL_INSTR                 g_dalvik_fill_instr_get_type() +#define G_DALVIK_FILL_INSTR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_fill_instr_get_type(), GDalvikFillInstr)) +#define G_IS_DALVIK_FILL_INSTR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_fill_instr_get_type())) +#define G_DALVIK_FILL_INSTR_GET_IFACE(inst)      (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_fill_instr_get_type(), GDalvikFillInstrIface)) + + +/* Définition générique d'une instruction d'architecture (instance) */ +typedef struct _GDalvikFillInstr GDalvikFillInstr; + +/* Définition générique d'une instruction d'architecture (classe) */ +typedef struct _GDalvikFillInstrClass GDalvikFillInstrClass; + + +/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */ +GType g_dalvik_fill_instr_get_type(void); + +/* Crée une pesudo-instruction Dalvik de remplissage. */ +GArchInstruction *g_dalvik_fill_instr_new(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +#endif  /* _ARCH_DALVIK_PSEUDO_FILL_H */ diff --git a/src/arch/dalvik/pseudo/switch.c b/src/arch/dalvik/pseudo/switch.c new file mode 100644 index 0000000..30511ac --- /dev/null +++ b/src/arch/dalvik/pseudo/switch.c @@ -0,0 +1,217 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * switch.c - prise en charge des instructions spéciales (packed|sparse)switch + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "switch.h" + + +#include <string.h>  + + +#include "../instruction-int.h" + + + +/* Définition générique d'une instruction d'architecture Dalvik (instance) */ +struct _GDalvikSwitchInstr +{ +    GDalvikInstruction parent;              /* A laisser en premier        */ + +    uint16_t switch_size;                   /* Taille du switch considéré  */ + +}; + +/* Définition générique d'une instruction d'architecture Dalvik (classe) */ +struct _GDalvikSwitchInstrClass +{ +    GDalvikInstructionClass parent;         /* A laisser en premier        */ + +}; + + + +/* Initialise la classe générique des instructions. */ +static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *); + +/* Initialise une instance d'opérande d'architecture. */ +static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); + + + +/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */ +G_DEFINE_TYPE(GDalvikSwitchInstr, g_dalvik_switch_instr, G_TYPE_DALVIK_INSTRUCTION); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe générique des instructions.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instance à initialiser.                              * +*                                                                             * +*  Description : Initialise une instance d'instruction d'architecture.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *instr) +{ +    GArchInstruction *parent;               /* Instance parente            */ + +    parent = G_ARCH_INSTRUCTION(instr); + +    parent->print = (print_instruction_fc)g_dalvik_switch_instr_print; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             * +*  Description : Crée une pesudo-instruction Dalvik de branchement.           * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_dalvik_switch_instr_new(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ +    GDalvikSwitchInstr *result;               /* Structure à retourner       */ +    uint16_t ident;                         /* Valeur lue dans le code     */ + +    result = g_object_new(G_TYPE_DALVIK_SWITCH_INSTR, NULL); + +    if (!read_u16(&ident, data, pos, len, SRE_LITTLE)) +        goto gdsin_bad; + +    if (ident != DPO_PACKED_SWITCH && ident != DPO_SPARSE_SWITCH) +        goto gdsin_bad; + +    G_DALVIK_INSTRUCTION(result)->ptype = ident; + +    if (!read_u16(&result->switch_size, data, pos, len, SRE_LITTLE)) +        goto gdsin_bad; + +    if (ident != DPO_PACKED_SWITCH) +        *pos += (1 + result->switch_size) * sizeof(uint32_t); +    else +        *pos += (2 * result->switch_size) * sizeof(uint32_t); + +    return G_ARCH_INSTRUCTION(result); + + gdsin_bad: + +    g_object_unref(result); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr  = instruction d'assemblage à représenter.             * +*                buffer = espace où placer ledit contenu.                     * +*                syntax = type de représentation demandée.                    * +*                                                                             * +*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +{ +    GArchInstruction *base;                 /* Version basique de l'objet  */ +    GBufferLine *line;                      /* Ligne de destination        */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */ +    char *bin_code;                         /* Tampon du code binaire      */ +    off_t i;                                /* Boucle de parcours          */ +    const char *key;                        /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ + +    base = G_ARCH_INSTRUCTION(instr); + +    line = g_code_buffer_append_new_line(buffer); + +    /* Adresse virtuelle ou physique */ + +    len = vmpa_to_string(base->address, msize, address); + +    g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW); + +    /* Code brut */ + +    bin_code = (char *)calloc(3 * 3 + 3, sizeof(char)); + +    for (i = 0; i < 3; i++) +    { +        if ((i + 1) < 3) +            snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]); +        else +            snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]); +    } + +    g_buffer_line_insert_text(line, BLC_BINARY, +                              bin_code, 3 * 3 + 2, RTT_RAW_CODE); + +    free(bin_code); + +    /* Instruction proprement dite */ + +    key = "<fill-array>"; +    klen = strlen(key); + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + +} diff --git a/src/arch/dalvik/pseudo/switch.h b/src/arch/dalvik/pseudo/switch.h new file mode 100644 index 0000000..602af48 --- /dev/null +++ b/src/arch/dalvik/pseudo/switch.h @@ -0,0 +1,57 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * switch.h - prototypes pour la prise en charge des instructions spéciales (packed|sparse)switch + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_DALVIK_PSEUDO_SWITCH_H +#define _ARCH_DALVIK_PSEUDO_SWITCH_H + + +#include "../instruction.h" +#include "../processor.h" + + +#include <glib-object.h> + + + +#define G_TYPE_DALVIK_SWITCH_INSTR                 g_dalvik_switch_instr_get_type() +#define G_DALVIK_SWITCH_INSTR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstr)) +#define G_IS_DALVIK_SWITCH_INSTR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_switch_instr_get_type())) +#define G_DALVIK_SWITCH_INSTR_GET_IFACE(inst)      (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstrIface)) + + +/* Définition générique d'une instruction d'architecture (instance) */ +typedef struct _GDalvikSwitchInstr GDalvikSwitchInstr; + +/* Définition générique d'une instruction d'architecture (classe) */ +typedef struct _GDalvikSwitchInstrClass GDalvikSwitchInstrClass; + + +/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */ +GType g_dalvik_switch_instr_get_type(void); + +/* Crée une pesudo-instruction Dalvik de branchement. */ +GArchInstruction *g_dalvik_switch_instr_new(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +#endif  /* _ARCH_DALVIK_PSEUDO_SWITCH_H */ diff --git a/src/arch/dalvik/specins.c b/src/arch/dalvik/specins.c deleted file mode 100644 index b6a7c4e..0000000 --- a/src/arch/dalvik/specins.c +++ /dev/null @@ -1,115 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * specins.c - gestion des instructions spéciales de la VM Dalvik - * - * Copyright (C) 2011 Cyrille Bagard - * - *  This file is part of OpenIDA. - * - *  OpenIDA 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 3 of the License, or - *  (at your option) any later version. - * - *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "specins.h" - - -#include "../../common/endianness.h" - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : ctx  = contexte lié à l'exécution du processeur.             * -*                data = flux de données à analyser.                           * -*                pos  = position courante dans ce flux.                       * -*                len  = taille totale des données à analyser.                 * -*                addr = adresse virtuelle de l'instruction.                   * -*                                                                             * -*  Description : Détermine si du code doit être écarté du traitement.         * -*                                                                             * -*  Retour      : true si une nouvelle zone de données est à écarter.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_dalvik_guess_special_instruction(GDalvikContext *ctx, const bin_t *data, off_t pos, off_t len, vmpa_t addr) -{ -    bool result;                            /* Bilan à retourner           */ -    uint16_t ident;                         /* Valeur lue dans le code     */ -    vmpa_t start;                           /* Début d'une zone de données */ -    vmpa_t end;                             /* Fin d'une zone de données   */ -    uint16_t switch_size;                   /* Taille du switch considéré  */ -    uint16_t array_width;                   /* Taille des éléments         */ -    uint32_t array_size;                    /* Taille du tableau           */ - -    /* Vérification astucieuse et rapide...*/ -    if (data[pos] != 0x00 /* DOP_NOP */) return false;  - -    if (!read_u16(&ident, data, &pos, len, SRE_LITTLE)) -        return false; - -    start = addr + sizeof(ident); -    end = start; - -    switch (ident) -    { -        case DID_PACKED_SWITCH: - -            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE)) -                return false; - -            end += sizeof(switch_size) + (1 + switch_size) * sizeof(uint32_t); - -            g_dalvik_context_skip_new_area(ctx, start, end); -            result = true; - -            break; - -        case DID_SPARSE_SWITCH: - -            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE)) -                return false; - -            end += sizeof(switch_size) + (2 * switch_size) * sizeof(uint32_t); - -            g_dalvik_context_skip_new_area(ctx, start, end); -            result = true; - -            break; - -        case DID_FILL_ARRAY_DATA: - -            if (!read_u16(&array_width, data, &pos, len, SRE_LITTLE)) -                return false; -            if (!read_u32(&array_size, data, &pos, len, SRE_LITTLE)) -                return false; - -            end += sizeof(array_width) + sizeof(array_size) -                + array_width * array_size; - -            g_dalvik_context_skip_new_area(ctx, start, end); -            result = true; - -            break; - -        default: -            result = false; -            break; - -    } - -    return result; - -} diff --git a/src/arch/dalvik/specins.h b/src/arch/dalvik/specins.h deleted file mode 100644 index 51cf6e9..0000000 --- a/src/arch/dalvik/specins.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * specins.h - prototypes pour la gestion des instructions spéciales de la VM Dalvik - * - * Copyright (C) 2011 Cyrille Bagard - * - *  This file is part of OpenIDA. - * - *  OpenIDA 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 3 of the License, or - *  (at your option) any later version. - * - *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. - */ - - -#ifndef _ARCH_DALVIK_SPECINS_H -#define _ARCH_DALVIK_SPECINS_H - - -#include <stdbool.h> - - -#include "../archbase.h" -#include "context.h" - - - -/* Speinss spéciales */ -typedef enum _DalvikIdents -{ -    DID_PACKED_SWITCH   = 0x0100,           /* Switch aux clefs compactes  */ -    DID_SPARSE_SWITCH   = 0x0200,           /* Switch aux clefs éclatées   */ -    DID_FILL_ARRAY_DATA = 0x0300            /* Contenu de tableau          */ - -} DalvikIdents; - - -/*  Détermine si du code doit être écarté du traitement. */ -bool g_dalvik_guess_special_instruction(GDalvikContext *, const bin_t *, off_t, off_t, vmpa_t); - - - -#endif  /* _ARCH_DALVIK_SPECINS_H */ diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 4eca0a5..4ffb5b0 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -33,6 +33,9 @@ +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +typedef void (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +  /* Traduit une instruction en version humainement lisible. */  typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const GExeFormat *, AsmSyntax); @@ -64,6 +67,7 @@ struct _GArchInstruction      InstructionLinkType *links_type;        /* Type des liens de dest.     */      size_t to_count;                        /* Nombre de ces destinations  */ +    print_instruction_fc print;             /* Imprime l'ensemble          */      get_instruction_text_fc get_text;       /* Texte humain équivalent     */      get_instruction_link_fc get_link;       /* Référence à une instruction */      is_instruction_return_fc is_return;     /* Retour de fonction ou pas ? */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 677a1a3..047ed86 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -46,6 +46,14 @@ static void g_arch_instruction_to_buffer(const GArchInstruction *, GBufferLine * +/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ + + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void _g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); + + +  /* Indique le type défini pour une instruction d'architecture. */  G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_CONTENT_EXPORTER); @@ -590,7 +598,7 @@ size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchI  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)  {      GBufferLine *line;                      /* Ligne de destination        */      char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ @@ -653,6 +661,31 @@ void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer  /******************************************************************************  *                                                                             * +*  Paramètres  : instr  = instruction d'assemblage à représenter.             * +*                buffer = espace où placer ledit contenu.                     * +*                syntax = type de représentation demandée.                    * +*                                                                             * +*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +{ +    if (instr->print != NULL) +        instr->print(instr, buffer, msize, content, syntax); + +    else +        _g_arch_instruction_print(instr, buffer, msize, content, syntax); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : instr = instruction d'origine à convertir.                   *  *                ctx   = contexte de la phase de décompilation.               *  *                                                                             * | 
