mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 15:10:53 +00:00
Move lua53 plugins to radare2-extras, available via r2pm
This reverts commit 16c2fd2fe4
.
This commit is contained in:
parent
737ca7ad81
commit
bbc508b324
@ -1,392 +0,0 @@
|
||||
#include <r_types.h>
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
#define Dprintf(...) eprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define Dprintf(...)
|
||||
#endif
|
||||
|
||||
|
||||
struct{
|
||||
int intSize;
|
||||
int sizeSize;
|
||||
int instructionSize;
|
||||
int luaIntSize;
|
||||
int luaNumberSize;
|
||||
RList* functionList;
|
||||
} lua53_data;
|
||||
|
||||
|
||||
static ut64 parseNumber(const ut8* data, ut64 bytesize){
|
||||
int i;
|
||||
ut64 res = 0;
|
||||
for(i = 0; i < bytesize;i++){
|
||||
res |= ((ut64)data[i]) << (8*i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define parseInt(data) parseNumber(data, lua53_data.intSize)
|
||||
#define parseSize(data) parseNumber(data, lua53_data.sizeSize)
|
||||
#define parseInstruction(data) parseNumber(data, lua53_data.instructionSize)
|
||||
#define parseLuaInt(data) parseNumber(data, lua53_data.luaIntSize)
|
||||
#define parseLuaNumber(data) parseNumber(data, lua53_data.luaNumberSize)
|
||||
|
||||
|
||||
typedef struct lua_function{
|
||||
ut64 offset;
|
||||
|
||||
char* name_ptr;//only valid in onFunction methon
|
||||
ut64 name_size;
|
||||
|
||||
ut64 lineDefined;
|
||||
ut64 lastLineDefined;
|
||||
ut8 numParams;
|
||||
ut8 isVarArg;
|
||||
ut8 maxStackSize;
|
||||
|
||||
struct lua_function* parent_func;//if != NULL, should always be valid
|
||||
|
||||
ut64 const_size;
|
||||
ut64 code_size;
|
||||
ut64 upvalue_size;
|
||||
ut64 protos_size;
|
||||
|
||||
ut64 const_offset;
|
||||
ut64 code_offset;
|
||||
ut64 upvalue_offset;
|
||||
ut64 protos_offset;
|
||||
ut64 debug_offset;
|
||||
|
||||
ut64 size;
|
||||
} LuaFunction;
|
||||
|
||||
RList *lua53_function_list;
|
||||
|
||||
struct lua_parse_struct;
|
||||
|
||||
typedef void (*OnFunction) (LuaFunction* function, struct lua_parse_struct* parseStruct);
|
||||
typedef void (*OnString) (const ut8* data, ut64 offset, ut64 size, struct lua_parse_struct* parseStruct);
|
||||
typedef void (*OnConst) (const ut8* data, ut64 offset, ut64 size, struct lua_parse_struct* parseStruct);
|
||||
|
||||
typedef struct lua_parse_struct{
|
||||
OnString onString;
|
||||
OnFunction onFunction;
|
||||
OnConst onConst;
|
||||
void* data;
|
||||
} ParseStruct;
|
||||
|
||||
LuaFunction* lua53findLuaFunctionByCodeAddr(ut64 addr){
|
||||
if(!lua53_data.functionList)
|
||||
return NULL;
|
||||
LuaFunction *function = NULL;
|
||||
RListIter *iter = NULL;
|
||||
r_list_foreach (lua53_data.functionList, iter, function) {
|
||||
if(function->code_offset + lua53_data.intSize <= addr && addr < function->const_offset)
|
||||
return function;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int storeLuaFunction(LuaFunction* function){
|
||||
if(!lua53_data.functionList){
|
||||
lua53_data.functionList = r_list_new ();
|
||||
if(!lua53_data.functionList){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
r_list_append (lua53_data.functionList,function);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static LuaFunction* findLuaFunction(ut64 addr){
|
||||
if(!lua53_data.functionList)
|
||||
return NULL;
|
||||
LuaFunction *function = NULL;
|
||||
RListIter *iter = NULL;
|
||||
r_list_foreach (lua53_data.functionList, iter, function) {
|
||||
Dprintf ("Search 0x%"PFMT64x"\n",function->offset);
|
||||
if(function->offset == addr)
|
||||
return function;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ut64 lua53parseHeader (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
ut64 lua53parseFunction (const ut8* data, ut64 offset, const ut64 size, LuaFunction* parent_func, ParseStruct* parseStruct);
|
||||
|
||||
static ut64 parseString (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
static ut64 parseStringR (const ut8* data, ut64 offset, const ut64 size, char** str_ptr, ut64* str_len, ParseStruct* parseStruct);
|
||||
static ut64 parseCode (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
static ut64 parseConstants (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
static ut64 parseUpvalues (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
static ut64 parseProtos (const ut8* data, ut64 offset, const ut64 size, LuaFunction* func, ParseStruct* parseStruct);
|
||||
static ut64 parseDebug (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct);
|
||||
|
||||
ut64 lua53parseHeader(const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
|
||||
if (data && offset + 16 <= size && !memcmp (data + offset, "\x1bLua", 4)) {//check the header
|
||||
offset += 4;
|
||||
if(data[offset + 0] != '\x53')//check version
|
||||
return 0;
|
||||
//skip format byte
|
||||
offset += 2;
|
||||
if(memcmp (data + offset, "\x19\x93\r\n\x1a\n", 6))//for version 5.3
|
||||
return 0;
|
||||
offset += 6;
|
||||
lua53_data.intSize = data[offset + 0];
|
||||
lua53_data.sizeSize = data[offset + 1];
|
||||
lua53_data.instructionSize = data[offset + 2];
|
||||
lua53_data.luaIntSize = data[offset + 3];
|
||||
lua53_data.luaNumberSize = data[offset + 4];
|
||||
|
||||
Dprintf ("Int Size: %i\n",lua53_data.intSize);
|
||||
Dprintf ("Size Size: %i\n",lua53_data.sizeSize);
|
||||
Dprintf ("Instruction Size: %i\n",lua53_data.instructionSize);
|
||||
Dprintf ("Lua Int Size: %i\n",lua53_data.luaIntSize);
|
||||
Dprintf ("Lua Number Size: %i\n",lua53_data.luaNumberSize);
|
||||
|
||||
offset += 5;
|
||||
if(offset + lua53_data.luaIntSize + lua53_data.luaNumberSize >= size)//check again the remainingsize because an int and number is appended to the header
|
||||
return 0;
|
||||
if(parseLuaInt (data + offset) != 0x5678)//check the appended integer
|
||||
return 0;
|
||||
offset += lua53_data.luaIntSize;
|
||||
ut64 num = parseLuaNumber (data + offset);
|
||||
if(*((double*)&num) != 370.5)//check the appended number
|
||||
return 0;
|
||||
offset += lua53_data.luaNumberSize;
|
||||
Dprintf ("Is a Lua Binary\n");
|
||||
return offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ut64 lua53parseFunction (const ut8* data, ut64 offset, const ut64 size, LuaFunction* parent_func, ParseStruct* parseStruct){
|
||||
Dprintf ("Function 0x%"PFMT64x"\n",offset);
|
||||
LuaFunction* function = findLuaFunction (offset);
|
||||
if(function){//if a function object was cached
|
||||
Dprintf ("Found cached Functione: 0x%"PFMT64x"\n",function->offset);
|
||||
|
||||
if(parseStruct != NULL && parseStruct->onString != NULL)
|
||||
parseConstants (data, function->const_offset, size, parseStruct);
|
||||
|
||||
parseProtos (data, function->protos_offset, size, function, parseStruct);
|
||||
|
||||
if(parseStruct != NULL && parseStruct->onString != NULL)
|
||||
parseDebug (data, function->debug_offset, size, parseStruct);
|
||||
|
||||
if(parseStruct != NULL && parseStruct->onFunction != NULL)
|
||||
parseStruct->onFunction (function, parseStruct);
|
||||
return offset + function->size;
|
||||
}else{
|
||||
ut64 baseoffset = offset;
|
||||
|
||||
function = R_NEW0 (LuaFunction);
|
||||
function->parent_func = parent_func;
|
||||
function->offset = offset;
|
||||
offset = parseStringR (data, offset, size, &function->name_ptr, &function->name_size, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
|
||||
function->lineDefined = parseInt (data + offset);
|
||||
Dprintf ("Line Defined: %"PFMT64x"\n",function->lineDefined);
|
||||
function->lastLineDefined = parseInt (data + offset + lua53_data.intSize);
|
||||
Dprintf ("Last Line Defined: %"PFMT64x"\n",function->lastLineDefined);
|
||||
offset += lua53_data.intSize*2;
|
||||
function->numParams = data[offset + 0];
|
||||
Dprintf ("Param Count: %d\n",function->numParams);
|
||||
function->isVarArg = data[offset + 1];
|
||||
Dprintf ("Is VarArgs: %d\n",function->isVarArg);
|
||||
function->maxStackSize = data[offset + 2];
|
||||
Dprintf ("Max Stack Size: %d\n",function->maxStackSize);
|
||||
offset += 3;
|
||||
|
||||
function->code_offset = offset;
|
||||
function->code_size = parseInt (data + offset);
|
||||
offset = parseCode (data, offset, size, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
function->const_offset = offset;
|
||||
function->const_size = parseInt (data + offset);
|
||||
offset = parseConstants (data, offset, size, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
function->upvalue_offset = offset;
|
||||
function->upvalue_size = parseInt (data + offset);
|
||||
offset = parseUpvalues (data, offset, size, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
function->protos_offset = offset;
|
||||
function->protos_size = parseInt (data + offset);
|
||||
offset = parseProtos (data, offset, size, function, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
function->debug_offset = offset;
|
||||
offset = parseDebug (data, offset, size, parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
|
||||
function->size = offset - baseoffset;
|
||||
if(parseStruct && parseStruct->onFunction)
|
||||
parseStruct->onFunction (function, parseStruct);
|
||||
if(!storeLuaFunction (function)){
|
||||
free (function);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
static ut64 parseCode(const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
ut64 length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
|
||||
if(offset + length*lua53_data.instructionSize >= size)
|
||||
return 0;
|
||||
Dprintf ("Function has %"PFMT64x" Instructions\n",length);
|
||||
|
||||
return offset + length*lua53_data.instructionSize;
|
||||
}
|
||||
static ut64 parseConstants(const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
ut64 length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
Dprintf ("Function has %"PFMT64x" Constants\n",length);
|
||||
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
Dprintf ("%d: ",i);
|
||||
ut8 type = data[offset + 0];
|
||||
offset += 1;
|
||||
switch(type){
|
||||
case 0://Nil
|
||||
Dprintf ("Nil\n");
|
||||
break;
|
||||
case 1://Boolean
|
||||
Dprintf ("Boolean %d\n",data[offset + 0]);
|
||||
offset += 1;
|
||||
break;
|
||||
case (3 | (0 << 4))://Number
|
||||
{
|
||||
#ifdef LUA_DEBUG
|
||||
ut64 num = parseLuaNumber (data + offset);
|
||||
Dprintf ("Number %f\n",*((double*)&num));
|
||||
#endif
|
||||
offset += lua53_data.luaNumberSize;
|
||||
}
|
||||
break;
|
||||
case (3 | (1 << 4))://Integer
|
||||
Dprintf ("Integer %"PFMT64x"\n",parseLuaInt (data + offset));
|
||||
offset += lua53_data.luaIntSize;
|
||||
break;
|
||||
case (4 | (0 << 4))://Short String
|
||||
case (4 | (1 << 4))://Long String
|
||||
offset = parseString (data,offset,size,parseStruct);
|
||||
break;
|
||||
default:
|
||||
Dprintf ("Invalid\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
static ut64 parseUpvalues(const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
ut64 length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
|
||||
Dprintf ("Function has %"PFMT64x" Upvalues\n",length);
|
||||
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
Dprintf ("%d: inStack: %d id: %d\n",i,data[offset + 0],data[offset + 1]);
|
||||
offset += 2;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
static ut64 parseProtos(const ut8* data, ut64 offset, const ut64 size, LuaFunction* func, ParseStruct* parseStruct){
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
ut64 length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
Dprintf ("Function has %"PFMT64x" Prototypes\n",length);
|
||||
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
offset = lua53parseFunction (data,offset,size,func,parseStruct);
|
||||
if(offset == 0)
|
||||
return 0;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
static ut64 parseDebug(const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
ut64 length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
|
||||
if(length != 0){
|
||||
Dprintf ("Instruction-Line Mappings %"PFMT64x"\n",length);
|
||||
if(offset + lua53_data.intSize * length >= size)
|
||||
return 0;
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
Dprintf ("Instruction %d Line %"PFMT64x"\n",i,parseInt (data + offset));
|
||||
offset += lua53_data.intSize;
|
||||
}
|
||||
}
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
if(length != 0){
|
||||
Dprintf ("LiveRanges: %"PFMT64x"\n",length);
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
Dprintf ("LiveRange %d:\n",i);
|
||||
offset = parseString (data,offset,size,parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
#ifdef LUA_DEBUG
|
||||
ut64 num1 = parseInt (data + offset);
|
||||
#endif
|
||||
offset += lua53_data.intSize;
|
||||
#ifdef LUA_DEBUG
|
||||
ut64 num2 = parseInt (data + offset);
|
||||
#endif
|
||||
offset += lua53_data.intSize;
|
||||
}
|
||||
}
|
||||
if(offset + lua53_data.intSize >= size)
|
||||
return 0;
|
||||
length = parseInt (data + offset);
|
||||
offset += lua53_data.intSize;
|
||||
if(length != 0){
|
||||
Dprintf ("Up-Values: %"PFMT64x"\n",length);
|
||||
int i;
|
||||
for(i = 0;i < length; i++){
|
||||
Dprintf ("Up-Value %d:\n",i);
|
||||
offset = parseString (data,offset,size,parseStruct);
|
||||
if(offset == 0) return 0;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
static ut64 parseString (const ut8* data, ut64 offset, const ut64 size, ParseStruct* parseStruct){
|
||||
return parseStringR (data,offset,size,0,0,parseStruct);
|
||||
}
|
||||
static ut64 parseStringR (const ut8* data, ut64 offset, const ut64 size, char** str_ptr, ut64* str_len, ParseStruct* parseStruct){
|
||||
ut64 functionNameSize = data[offset + 0];
|
||||
offset += 1;
|
||||
if(functionNameSize == 0xFF){
|
||||
functionNameSize = parseSize(data + offset);
|
||||
offset += lua53_data.sizeSize;
|
||||
}
|
||||
if(functionNameSize != 0){
|
||||
if(str_ptr)
|
||||
*str_ptr = (char*)data + offset;
|
||||
if(str_len)
|
||||
*str_len = functionNameSize - 1;
|
||||
if(parseStruct && parseStruct->onString)
|
||||
parseStruct->onString (data, offset, functionNameSize - 1, parseStruct);
|
||||
Dprintf ("String %.*s\n",(int)(functionNameSize - 1),data + offset);
|
||||
offset += functionNameSize - 1;
|
||||
}
|
||||
return offset;
|
||||
}
|
@ -12,7 +12,7 @@ all: ${ALL_TARGETS} ;
|
||||
|
||||
ALL_TARGETS=
|
||||
# TODO: rename to enabled plugins
|
||||
ARCHS=null.mk x86_udis.mk ppc_gnu.mk ppc_cs.mk arm_gnu.mk avr.mk xap.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk v850.mk msp430.mk sparc_gnu.mk sparc_cs.mk x86_cs.mk cris.mk 6502.mk snes.mk riscv.mk vax.mk xtensa.mk rsp.mk lua53.mk
|
||||
ARCHS=null.mk x86_udis.mk ppc_gnu.mk ppc_cs.mk arm_gnu.mk avr.mk xap.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk v850.mk msp430.mk sparc_gnu.mk sparc_cs.mk x86_cs.mk cris.mk 6502.mk snes.mk riscv.mk vax.mk xtensa.mk rsp.mk
|
||||
include $(ARCHS)
|
||||
|
||||
clean:
|
||||
|
@ -1,223 +0,0 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_anal.h>
|
||||
#include "../../asm/arch/lua53/lua53.c"
|
||||
#include "../arch/lua53/lua53_parser.c"
|
||||
|
||||
static int lua53_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
if (!op) return 0;
|
||||
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
const ut32 instruction = getInstruction (data);
|
||||
ut32 extraArg = 0;
|
||||
op->addr = addr;
|
||||
op->size = 4;
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->eob = false;
|
||||
if(GET_OPCODE (instruction) > OP_EXTRAARG)
|
||||
return op->size;
|
||||
op->mnemonic = strdup(instruction_names[GET_OPCODE (instruction)]);
|
||||
switch( GET_OPCODE (instruction) ){
|
||||
case OP_MOVE:/* A B R(A) := R(B) */
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
break;
|
||||
case OP_LOADK:/* A Bx R(A) := Kst(Bx) */
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
case OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
extraArg = getInstruction (data + 4);
|
||||
if(GET_OPCODE (extraArg) == OP_EXTRAARG){
|
||||
op->size = 8;
|
||||
}
|
||||
break;
|
||||
case OP_LOADBOOL:/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->val = !!GETARG_B (instruction);
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_LOADNIL:/* A B R(A), R(A+1), ..., R(A+B) := nil */
|
||||
break;
|
||||
case OP_GETUPVAL:/* A B R(A) := UpValue[B] */
|
||||
case OP_GETTABUP:/* A B C R(A) := UpValue[B][RK(C)] */
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
case OP_GETTABLE:/* A B C R(A) := R(B)[RK(C)] */
|
||||
break;
|
||||
|
||||
case OP_SETTABUP:/* A B C UpValue[A][RK(B)] := RK(C) */
|
||||
case OP_SETUPVAL:/* A B UpValue[B] := R(A) */
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case OP_SETTABLE:/* A B C R(A)[RK(B)] := RK(C) */
|
||||
break;
|
||||
case OP_NEWTABLE:/* A B C R(A) := {} (size = B,C) */
|
||||
op->type = R_ANAL_OP_TYPE_NEW;
|
||||
break;
|
||||
case OP_SELF:/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||
break;
|
||||
case OP_ADD:/* A B C R(A) := RK(B) + RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case OP_SUB:/* A B C R(A) := RK(B) - RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case OP_MUL:/* A B C R(A) := RK(B) * RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
break;
|
||||
case OP_MOD:/* A B C R(A) := RK(B) % RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_MOD;
|
||||
break;
|
||||
case OP_POW:/* A B C R(A) := RK(B) ^ RK(C) */
|
||||
break;
|
||||
case OP_DIV:/* A B C R(A) := RK(B) / RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
case OP_IDIV:/* A B C R(A) := RK(B) // RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
case OP_BAND:/* A B C R(A) := RK(B) & RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case OP_BOR:/* A B C R(A) := RK(B) | RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case OP_BXOR:/* A B C R(A) := RK(B) ~ RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case OP_SHL:/* A B C R(A) := RK(B) << RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case OP_SHR:/* A B C R(A) := RK(B) >> RK(C) */
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case OP_UNM:/* A B R(A) := -R(B) */
|
||||
break;
|
||||
case OP_BNOT:/* A B R(A) := ~R(B) */
|
||||
op->type = R_ANAL_OP_TYPE_CPL;
|
||||
break;
|
||||
case OP_NOT:/* A B R(A) := not R(B) */
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
break;
|
||||
case OP_LEN:/* A B R(A) := length of R(B) */
|
||||
break;
|
||||
case OP_CONCAT:/* A B C R(A) := R(B).. ... ..R(C) */
|
||||
break;
|
||||
case OP_JMP:/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 4*(GETARG_sBx (instruction));
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_EQ:/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_LT:/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_LE:/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_TEST:/* A C if not (R(A) <=> C) then pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_TESTSET:/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||
op->type = R_ANAL_OP_TYPE_CMOV;
|
||||
op->jump = op->addr + 8;
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_CALL:/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
op->type = R_ANAL_OP_TYPE_RCALL;
|
||||
break;
|
||||
case OP_TAILCALL:/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
op->type = R_ANAL_OP_TYPE_RCALL;
|
||||
op->type2 = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = true;
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->stackptr = -4;
|
||||
break;
|
||||
case OP_RETURN:/* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = true;
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->stackptr = -4;
|
||||
break;
|
||||
case OP_FORLOOP:/* A sBx R(A)+=R(A+2);
|
||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 4 + 4*(GETARG_sBx (instruction));
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_FORPREP:/* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = op->addr + 4 + 4*(GETARG_sBx (instruction));
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_TFORCALL:/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
op->type = R_ANAL_OP_TYPE_RCALL;
|
||||
break;
|
||||
case OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = op->addr + 4 + 4*(GETARG_sBx (instruction));
|
||||
op->fail = op->addr + 4;
|
||||
break;
|
||||
case OP_SETLIST:/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case OP_CLOSURE:/* A Bx R(A) := closure(KPROTO[Bx]) */
|
||||
case OP_VARARG:/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
|
||||
case OP_EXTRAARG:/* Ax extra (larger) argument for previous opcode */
|
||||
break;
|
||||
}
|
||||
return op->size;
|
||||
}
|
||||
static int lua53_anal_fcn(RAnal *a, RAnalFunction *fcn, ut64 addr, const ut8 *data, int len, int reftype){
|
||||
Dprintf ("Analyze Function: 0x%"PFMT64x"\n",addr);
|
||||
LuaFunction* function = lua53findLuaFunctionByCodeAddr (addr);
|
||||
if(function){
|
||||
fcn->maxstack = function->maxStackSize;
|
||||
fcn->nargs = function->numParams;
|
||||
}
|
||||
fcn->addr = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finit(void *user) {
|
||||
if(lua53_data.functionList){
|
||||
r_list_free (lua53_data.functionList);
|
||||
lua53_data.functionList = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
RAnalPlugin r_anal_plugin_lua53 = {
|
||||
.name = "lua53",
|
||||
.desc = "LUA 5.3 analysis plugin",
|
||||
.arch = "lua53",
|
||||
.license = "MIT",
|
||||
.bits = 32,
|
||||
.desc = "LUA 5.3 VM code analysis plugin",
|
||||
.op = &lua53_anal_op,
|
||||
.fcn = &lua53_anal_fcn,
|
||||
.esil = false,
|
||||
.fini = &finit,
|
||||
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_lua53,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
OBJ_LUA53=anal_lua53.o
|
||||
|
||||
include $(CURDIR)capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_LUA53)
|
||||
TARGET_LUA53=anal_lua53.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_LUA53}
|
||||
|
||||
${TARGET_LUA53}: ${OBJ_LUA53}
|
||||
${CC} ${CFLAGS} $(call libname,anal_lua53) $(CS_CFLAGS) \
|
||||
-o anal_LUA53.${EXT_SO} ${OBJ_LUA53} $(CS_LDFLAGS)
|
@ -1,415 +0,0 @@
|
||||
|
||||
#include <r_asm.h>
|
||||
#include <stdio.h>
|
||||
#include "lua53.h"
|
||||
|
||||
#define isAlpha(x) (('a' <= (x) && 'z' >= (x)) || ('A' <= (x) && 'Z' >= (x)))
|
||||
#define isNumeric(x) ('0' <= (x) && '9' >= (x))
|
||||
#define isWhitespace(x) (' ' == (x) || '\t' == (x))
|
||||
#define isComment(x) (';' == (x))
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
#define Dprintf(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define Dprintf(...)
|
||||
#endif
|
||||
|
||||
#define doParse0(inc,func,str) {\
|
||||
int temp = func(str + inc);\
|
||||
if(temp < 0) {\
|
||||
Dprintf ("%i from %s in String %s\n",temp,#func,str + inc);\
|
||||
return -1;\
|
||||
}\
|
||||
inc += temp; \
|
||||
}
|
||||
#define doParse1(inc,func,str,...) {\
|
||||
int temp = func(str + inc,__VA_ARGS__);\
|
||||
if(temp < 0) {\
|
||||
Dprintf ("%i from %s in String %s\n",temp,#func,str + inc);\
|
||||
return -1;\
|
||||
}\
|
||||
inc += temp; \
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
PARAMETER_A,
|
||||
PARAMETER_B,
|
||||
PARAMETER_C,
|
||||
PARAMETER_Ax,
|
||||
PARAMETER_Bx,
|
||||
PARAMETER_sBx
|
||||
}Parameter;
|
||||
|
||||
ut32* current_write_prt;
|
||||
ut32 current_write_index;
|
||||
|
||||
static int findNextWordStart (const char* str);
|
||||
|
||||
static int parseParameters (const char* str,OpCode opCode);
|
||||
|
||||
static int parseParameter (const char* str,Parameter parameter);
|
||||
|
||||
static int parseNextInstruction (const char* str);
|
||||
|
||||
static int parseWhitespaces (const char* str);
|
||||
|
||||
const char* instruction_names[] = {
|
||||
"move","loadk","loadkx","loadbool","loadnil","getupval","gettabup","gettable","settabup","setupval","settable","newtable","self","add","sub","mul","mod",
|
||||
"pow","div","idiv","band","bor","bxor","shl","shr","unm","bnot","not","len","concat","jmp","eq","lt","le",
|
||||
"test","testset","call","tailcall","return","forloop","forprep","tforcall","tforloop","setlist","closure","vararg","extraarg",0
|
||||
};
|
||||
|
||||
static ut32 getInstruction (const ut8* data){
|
||||
ut32 instruction = 0;
|
||||
instruction |= data[3] << 24;
|
||||
instruction |= data[2] << 16;
|
||||
instruction |= data[1] << 8;
|
||||
instruction |= data[0] << 0;
|
||||
return instruction;
|
||||
}
|
||||
static void setInstruction (ut32 opcode,ut8* data){
|
||||
data[3] = opcode >> 24;
|
||||
data[2] = opcode >> 16;
|
||||
data[1] = opcode >> 8;
|
||||
data[0] = opcode >> 0;
|
||||
}
|
||||
|
||||
static int findNextWordStart (const char* str){
|
||||
int chars_skipped = 0;
|
||||
char c;
|
||||
char comment_char;
|
||||
while(1){
|
||||
doParse0(chars_skipped,parseWhitespaces,str);
|
||||
c = str[chars_skipped];
|
||||
if( isAlpha(c) || isNumeric(c) || c == '-' ){//if alphanumeric character return position
|
||||
return chars_skipped;
|
||||
}else if( c == ';' ){//skip comment
|
||||
do{
|
||||
++chars_skipped;
|
||||
if( c == '\0'){
|
||||
Dprintf ("Invalic Char 0x%02x\n",c);
|
||||
return -1;
|
||||
}
|
||||
comment_char = str[chars_skipped];
|
||||
}while(comment_char != '\n');//if no newline
|
||||
}else if( c == '\n' ){//skip comment
|
||||
++chars_skipped;
|
||||
continue;
|
||||
}else if( c == '\0'){
|
||||
break;
|
||||
}else{
|
||||
Dprintf ("Invalic Char 0x%02x\n",c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Dprintf ("Parsed %i empty Chars\n",chars_skipped);
|
||||
return chars_skipped;
|
||||
}
|
||||
static int parseNextInstruction (const char* str){
|
||||
int chars_skipped = 0;
|
||||
doParse0(chars_skipped,findNextWordStart,str);
|
||||
const char* str_ptr = str + chars_skipped;
|
||||
|
||||
int i;
|
||||
for (i = 0;instruction_names[i] != 0;++i) {//iterate over instruction strings
|
||||
bool accepted = true;
|
||||
int j;
|
||||
for(j = 0;instruction_names[i][j] != '\0';++j){//iterate over characters
|
||||
if( !((instruction_names[i][j] == str_ptr[j]) || (instruction_names[i][j] == (str_ptr[j] - 'A' + 'a'))) ){//if char or uppercase char does not match
|
||||
accepted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(((isWhitespace(str_ptr[j]) || isComment(str_ptr[j])) && accepted)){//if this is longest match possible
|
||||
//write operation
|
||||
chars_skipped += j;
|
||||
Dprintf ("Opcode %i Instruction %s\n",i,instruction_names[i]);
|
||||
|
||||
SET_OPCODE(current_write_prt[current_write_index],i);//sets the opcode
|
||||
|
||||
doParse1(chars_skipped,parseParameters,str,i);//Parse parameters
|
||||
|
||||
++current_write_index;//finished parsing an instruction so increase index
|
||||
return chars_skipped;
|
||||
}
|
||||
}
|
||||
Dprintf ("Error\n");
|
||||
return -1;
|
||||
}
|
||||
static int parseWhitespaces (const char* str){
|
||||
int skipped_whitespace = 0;
|
||||
char c = str[skipped_whitespace];
|
||||
while( isWhitespace(c) ){
|
||||
c = str[++skipped_whitespace];
|
||||
}
|
||||
Dprintf ("Parsed %i Whitespaces\n",skipped_whitespace);
|
||||
return skipped_whitespace;
|
||||
}
|
||||
|
||||
static int parseParameters (const char* str,OpCode opCode){
|
||||
int chars_skipped = 0;
|
||||
doParse0(chars_skipped,parseWhitespaces,str);
|
||||
switch(opCode){
|
||||
case OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
break;
|
||||
case OP_MOVE:/* A B R(A) := R(B) */
|
||||
case OP_LOADNIL:/* A B R(A), R(A+1), ..., R(A+B) := nil */
|
||||
case OP_GETUPVAL:/* A B R(A) := UpValue[B] */
|
||||
case OP_SETUPVAL:/* A B UpValue[B] := R(A) */
|
||||
case OP_UNM:/* A B R(A) := -R(B) */
|
||||
case OP_BNOT:/* A B R(A) := ~R(B) */
|
||||
case OP_NOT:/* A B R(A) := not R(B) */
|
||||
case OP_LEN:/* A B R(A) := length of R(B) */
|
||||
case OP_RETURN:/* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
case OP_VARARG:/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_B);
|
||||
break;
|
||||
case OP_TEST:/* A C if not (R(A) <=> C) then pc++ */
|
||||
case OP_TFORCALL:/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_C);
|
||||
break;
|
||||
case OP_LOADK:/* A Bx R(A) := Kst(Bx) */
|
||||
case OP_CLOSURE:/* A Bx R(A) := closure(KPROTO[Bx]) */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_Bx);
|
||||
break;
|
||||
case OP_LOADBOOL:/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||
case OP_GETTABUP:/* A B C R(A) := UpValue[B][RK(C)] */
|
||||
case OP_GETTABLE:/* A B C R(A) := R(B)[RK(C)] */
|
||||
case OP_SETTABUP:/* A B C UpValue[A][RK(B)] := RK(C) */
|
||||
case OP_SETTABLE:/* A B C R(A)[RK(B)] := RK(C) */
|
||||
case OP_NEWTABLE:/* A B C R(A) := {} (size = B,C) */
|
||||
case OP_SELF:/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||
case OP_ADD:/* A B C R(A) := RK(B) + RK(C) */
|
||||
case OP_SUB:/* A B C R(A) := RK(B) - RK(C) */
|
||||
case OP_MUL:/* A B C R(A) := RK(B) * RK(C) */
|
||||
case OP_MOD:/* A B C R(A) := RK(B) % RK(C) */
|
||||
case OP_POW:/* A B C R(A) := RK(B) ^ RK(C) */
|
||||
case OP_DIV:/* A B C R(A) := RK(B) / RK(C) */
|
||||
case OP_IDIV:/* A B C R(A) := RK(B) // RK(C) */
|
||||
case OP_BAND:/* A B C R(A) := RK(B) & RK(C) */
|
||||
case OP_BOR:/* A B C R(A) := RK(B) | RK(C) */
|
||||
case OP_BXOR:/* A B C R(A) := RK(B) ~ RK(C) */
|
||||
case OP_SHL:/* A B C R(A) := RK(B) << RK(C) */
|
||||
case OP_SHR:/* A B C R(A) := RK(B) >> RK(C) */
|
||||
case OP_CONCAT:/* A B C R(A) := R(B).. ... ..R(C) */
|
||||
case OP_EQ:/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
case OP_LT:/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
case OP_LE:/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
case OP_TESTSET:/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||
case OP_CALL:/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
case OP_TAILCALL:/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
case OP_SETLIST:/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_B);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_C);
|
||||
break;
|
||||
case OP_JMP:/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
||||
case OP_FORLOOP:/* A sBx R(A)+=R(A+2);
|
||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
||||
case OP_FORPREP:/* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
case OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_A);
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_sBx);
|
||||
break;
|
||||
case OP_EXTRAARG:/* Ax extra (larger) argument for previous opcode */
|
||||
doParse1(chars_skipped,parseParameter,str,PARAMETER_Ax);
|
||||
break;
|
||||
}
|
||||
return chars_skipped;
|
||||
}
|
||||
static int parseParameter (const char* str,Parameter parameter){
|
||||
int skipped_chars = findNextWordStart (str);
|
||||
int resultingNumber = 0;
|
||||
bool negative = false;
|
||||
if(str[skipped_chars] == '-'){
|
||||
negative = true;
|
||||
++skipped_chars;
|
||||
}
|
||||
char c = str[skipped_chars];
|
||||
if( !isNumeric(c) ){
|
||||
return -1;
|
||||
}
|
||||
while( isNumeric(c) ){
|
||||
resultingNumber *= 10;
|
||||
resultingNumber += c - '0';
|
||||
c = str[++skipped_chars];
|
||||
}
|
||||
resultingNumber = negative ? resultingNumber*(-1) : resultingNumber;
|
||||
Dprintf ("Parsed Parameter %i\n",resultingNumber);
|
||||
if(parameter != PARAMETER_sBx && resultingNumber < 0){
|
||||
return -1;
|
||||
}
|
||||
switch(parameter){
|
||||
case PARAMETER_A:
|
||||
SETARG_A(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
case PARAMETER_B:
|
||||
SETARG_B(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
case PARAMETER_C:
|
||||
SETARG_C(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
case PARAMETER_Ax:
|
||||
SETARG_Ax(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
case PARAMETER_Bx:
|
||||
SETARG_Bx(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
case PARAMETER_sBx:
|
||||
SETARG_sBx(current_write_prt[current_write_index],resultingNumber);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return skipped_chars;
|
||||
}
|
||||
|
||||
int lua53asm (RAsmOp *op, const char *s){
|
||||
int parsed = 0;
|
||||
Dprintf ("%s\n",s);
|
||||
ut32 instruction;
|
||||
current_write_prt = &instruction;
|
||||
current_write_index = 0;
|
||||
doParse0 (parsed,parseNextInstruction,s);
|
||||
|
||||
setInstruction (instruction,op->buf);
|
||||
|
||||
Dprintf ("%d\n",parsed);
|
||||
Dprintf ("%08x\n",instruction);
|
||||
return 4;
|
||||
}
|
||||
|
||||
int lua53dissasm (RAsmOp *op, const ut8 *buf, int len){
|
||||
ut32 instruction = 0;
|
||||
if(len < 4)
|
||||
return 0;
|
||||
instruction = getInstruction (buf);
|
||||
|
||||
OpCode operator = GET_OPCODE (instruction);
|
||||
|
||||
Dprintf ("Parse Bytes %08x\n",((ut32*)buf)[0]);
|
||||
|
||||
switch(operator){
|
||||
case OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
||||
sprintf (op->buf_asm, "%s %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction));
|
||||
break;
|
||||
case OP_MOVE:/* A B R(A) := R(B) */
|
||||
case OP_LOADNIL:/* A B R(A), R(A+1), ..., R(A+B) := nil */
|
||||
case OP_GETUPVAL:/* A B R(A) := UpValue[B] */
|
||||
case OP_SETUPVAL:/* A B UpValue[B] := R(A) */
|
||||
case OP_UNM:/* A B R(A) := -R(B) */
|
||||
case OP_BNOT:/* A B R(A) := ~R(B) */
|
||||
case OP_NOT:/* A B R(A) := not R(B) */
|
||||
case OP_LEN:/* A B R(A) := length of R(B) */
|
||||
case OP_RETURN:/* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
case OP_VARARG:/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
|
||||
sprintf (op->buf_asm, "%s %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction));
|
||||
break;
|
||||
case OP_TEST:/* A C if not (R(A) <=> C) then pc++ */
|
||||
case OP_TFORCALL:/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
sprintf (op->buf_asm, "%s %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_C(instruction));
|
||||
break;
|
||||
case OP_LOADK:/* A Bx R(A) := Kst(Bx) */
|
||||
sprintf (op->buf_asm, "%s %i Kst(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_Bx(instruction));
|
||||
break;
|
||||
case OP_CLOSURE:/* A Bx R(A) := closure(KPROTO[Bx]) */
|
||||
sprintf (op->buf_asm, "%s %i KPROTO(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_Bx(instruction));
|
||||
break;
|
||||
case OP_LOADBOOL:/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||
case OP_NEWTABLE:/* A B C R(A) := {} (size = B,C) */
|
||||
case OP_CONCAT:/* A B C R(A) := R(B).. ... ..R(C) */
|
||||
case OP_TESTSET:/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||
case OP_CALL:/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
case OP_TAILCALL:/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
case OP_SETLIST:/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
sprintf (op->buf_asm, "%s %i %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction),GETARG_C(instruction));
|
||||
break;
|
||||
case OP_SELF:/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||
case OP_GETTABUP:/* A B C R(A) := UpValue[B][RK(C)] */
|
||||
case OP_GETTABLE:/* A B C R(A) := R(B)[RK(C)] */
|
||||
if(GETARG_C(instruction) & 0x100)
|
||||
sprintf (op->buf_asm, "%s %i %i K(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction),GETARG_C(instruction) & 0xFF);
|
||||
else
|
||||
sprintf (op->buf_asm, "%s %i %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction),GETARG_C(instruction));
|
||||
break;
|
||||
case OP_SETTABUP:/* A B C UpValue[A][RK(B)] := RK(C) */
|
||||
case OP_SETTABLE:/* A B C R(A)[RK(B)] := RK(C) */
|
||||
case OP_ADD:/* A B C R(A) := RK(B) + RK(C) */
|
||||
case OP_SUB:/* A B C R(A) := RK(B) - RK(C) */
|
||||
case OP_MUL:/* A B C R(A) := RK(B) * RK(C) */
|
||||
case OP_MOD:/* A B C R(A) := RK(B) % RK(C) */
|
||||
case OP_POW:/* A B C R(A) := RK(B) ^ RK(C) */
|
||||
case OP_DIV:/* A B C R(A) := RK(B) / RK(C) */
|
||||
case OP_IDIV:/* A B C R(A) := RK(B) // RK(C) */
|
||||
case OP_BAND:/* A B C R(A) := RK(B) & RK(C) */
|
||||
case OP_BOR:/* A B C R(A) := RK(B) | RK(C) */
|
||||
case OP_BXOR:/* A B C R(A) := RK(B) ~ RK(C) */
|
||||
case OP_SHL:/* A B C R(A) := RK(B) << RK(C) */
|
||||
case OP_SHR:/* A B C R(A) := RK(B) >> RK(C) */
|
||||
case OP_EQ:/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
case OP_LT:/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
case OP_LE:/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
|
||||
if(GETARG_B(instruction) & 0x100){
|
||||
if(GETARG_C(instruction) & 0x100)
|
||||
sprintf (op->buf_asm, "%s %i K(%i) K(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction) & 0xFF,GETARG_C(instruction) & 0xFF);
|
||||
else
|
||||
sprintf (op->buf_asm, "%s %i K(%i) %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction) & 0xFF,GETARG_C(instruction));
|
||||
}else{
|
||||
if(GETARG_C(instruction) & 0x100)
|
||||
sprintf (op->buf_asm, "%s %i %i K(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction),GETARG_C(instruction) & 0xFF);
|
||||
else
|
||||
sprintf (op->buf_asm, "%s %i %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_B(instruction),GETARG_C(instruction));
|
||||
}
|
||||
break;
|
||||
case OP_JMP:/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
||||
case OP_FORLOOP:/* A sBx R(A)+=R(A+2);
|
||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
||||
case OP_FORPREP:/* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
case OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
|
||||
sprintf (op->buf_asm, "%s %i %i", instruction_names[GET_OPCODE(instruction)], GETARG_A(instruction),GETARG_sBx(instruction));
|
||||
break;
|
||||
case OP_EXTRAARG:/* Ax extra (larger) argument for previous opcode */
|
||||
sprintf (op->buf_asm, "%s Kst(%i)", instruction_names[GET_OPCODE(instruction)], GETARG_Ax(instruction));
|
||||
break;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAIN_ASM
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
char *c = "move 1 2\n forprep 13 -2";
|
||||
int p = 0;
|
||||
current_write_prt = malloc(8);
|
||||
current_write_index = 0;
|
||||
Dprintf ("Parsing String: %s\n",c);
|
||||
Dprintf ("-----------------------\n");
|
||||
doParse0(p,parseNextInstruction,c,(int)strlen(c));
|
||||
Dprintf ("Parsed Characters %i\n",p);
|
||||
Dprintf ("%d %08x\n", current_write_index, current_write_prt[current_write_index-1]);
|
||||
|
||||
Dprintf ("------------\n");
|
||||
|
||||
doParse0(p,parseNextInstruction,c,(int)strlen(c));
|
||||
Dprintf ("Parsed Characters %i\n",p);
|
||||
Dprintf ("%d %08x\n", current_write_index, current_write_prt[current_write_index-1]);
|
||||
|
||||
Dprintf ("------------\n");
|
||||
|
||||
RAsmOp* asmOp = (RAsmOp*) malloc(sizeof(RAsmOp));
|
||||
int advanced = lua53dissasm (asmOp,(const char *)current_write_prt,4);
|
||||
|
||||
Dprintf ("%s\n",asmOp->buf_asm);
|
||||
lua53dissasm (asmOp,(const char *)current_write_prt + advanced,4);
|
||||
Dprintf ("%s\n",asmOp->buf_asm);
|
||||
|
||||
free(current_write_prt);
|
||||
return 0;
|
||||
}
|
||||
#endif //MAIN_ASM
|
@ -1,230 +0,0 @@
|
||||
/*
|
||||
** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp $
|
||||
** Opcodes for Lua virtual machine
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2017 Lua.org, PUC-Rio.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef lopcodes_h
|
||||
#define lopcodes_h
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/*===========================================================================
|
||||
We assume that instructions are unsigned numbers.
|
||||
All instructions have an opcode in the first 6 bits.
|
||||
Instructions can have the following fields:
|
||||
'A' : 8 bits
|
||||
'B' : 9 bits
|
||||
'C' : 9 bits
|
||||
'Ax' : 26 bits ('A', 'B', and 'C' together)
|
||||
'Bx' : 18 bits ('B' and 'C' together)
|
||||
'sBx' : signed Bx
|
||||
|
||||
A signed argument is represented in excess K; that is, the number
|
||||
value is the unsigned value minus K. K is exactly the maximum value
|
||||
for that argument (so that -max is represented by 0, and +max is
|
||||
represented by 2*max), which is half the maximum for the corresponding
|
||||
unsigned argument.
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
|
||||
|
||||
#define cast(x,y) ((x)y)
|
||||
|
||||
/*
|
||||
** size and position of opcode arguments.
|
||||
*/
|
||||
#define SIZE_C 9
|
||||
#define SIZE_B 9
|
||||
#define SIZE_Bx (SIZE_C + SIZE_B)
|
||||
#define SIZE_A 8
|
||||
#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
|
||||
|
||||
#define SIZE_OP 6
|
||||
|
||||
#define POS_OP 0
|
||||
#define POS_A (POS_OP + SIZE_OP)
|
||||
#define POS_C (POS_A + SIZE_A)
|
||||
#define POS_B (POS_C + SIZE_C)
|
||||
#define POS_Bx POS_C
|
||||
#define POS_Ax POS_A
|
||||
|
||||
#define MAX_INT INT_MAX /* maximum value of an int */
|
||||
|
||||
#define LUAI_BITSINT 32
|
||||
|
||||
/*
|
||||
** limits for opcode arguments.
|
||||
** we use (signed) int to manipulate most arguments,
|
||||
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
|
||||
*/
|
||||
#if SIZE_Bx < LUAI_BITSINT-1
|
||||
#define MAXARG_Bx ((1<<SIZE_Bx)-1)
|
||||
#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */
|
||||
#else
|
||||
#define MAXARG_Bx MAX_INT
|
||||
#define MAXARG_sBx MAX_INT
|
||||
#endif
|
||||
|
||||
#if SIZE_Ax < LUAI_BITSINT-1
|
||||
#define MAXARG_Ax ((1<<SIZE_Ax)-1)
|
||||
#else
|
||||
#define MAXARG_Ax MAX_INT
|
||||
#endif
|
||||
|
||||
|
||||
#define MAXARG_A ((1<<SIZE_A)-1)
|
||||
#define MAXARG_B ((1<<SIZE_B)-1)
|
||||
#define MAXARG_C ((1<<SIZE_C)-1)
|
||||
|
||||
/* creates a mask with 'n' 1 bits at position 'p' */
|
||||
#define MASK1(n,p) ((~((~0)<<(n)))<<(p))
|
||||
|
||||
/* creates a mask with 'n' 0 bits at position 'p' */
|
||||
#define MASK0(n,p) (~MASK1(n,p))
|
||||
|
||||
static ut32 getInstruction(const ut8* data);
|
||||
static void setInstruction(ut32 opcode, ut8* data);
|
||||
|
||||
|
||||
/*
|
||||
** the following macros help to manipulate instructions
|
||||
*/
|
||||
|
||||
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
|
||||
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
|
||||
((cast(ut32, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
|
||||
|
||||
#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0)))
|
||||
#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
|
||||
((cast(ut32, v)<<pos)&MASK1(size,pos))))
|
||||
|
||||
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
|
||||
#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
|
||||
|
||||
#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
|
||||
#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B)
|
||||
|
||||
#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
|
||||
#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C)
|
||||
|
||||
#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx)
|
||||
#define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx)
|
||||
|
||||
#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax)
|
||||
#define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax)
|
||||
|
||||
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
|
||||
#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
|
||||
|
||||
|
||||
#define CREATE_ABC(o,a,b,c) ((cast(ut32, o)<<POS_OP) \
|
||||
| (cast(ut32, a)<<POS_A) \
|
||||
| (cast(ut32, b)<<POS_B) \
|
||||
| (cast(ut32, c)<<POS_C))
|
||||
|
||||
#define CREATE_ABx(o,a,bc) ((cast(ut32, o)<<POS_OP) \
|
||||
| (cast(ut32, a)<<POS_A) \
|
||||
| (cast(ut32, bc)<<POS_Bx))
|
||||
|
||||
#define CREATE_Ax(o,a) ((cast(ut32)<<POS_OP) \
|
||||
| (cast(ut32, a)<<POS_Ax))
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
/*----------------------------------------------------------------------
|
||||
name args description
|
||||
------------------------------------------------------------------------*/
|
||||
OP_MOVE,/* A B R(A) := R(B) */
|
||||
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
|
||||
OP_LOADKX,/* A R(A) := Kst(extra arg) */
|
||||
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||
OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */
|
||||
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
|
||||
|
||||
OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
|
||||
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
|
||||
|
||||
OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
|
||||
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
|
||||
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
|
||||
|
||||
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
|
||||
|
||||
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||
|
||||
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
|
||||
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
|
||||
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
|
||||
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
|
||||
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
|
||||
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
|
||||
OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
|
||||
OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
|
||||
OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
|
||||
OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */
|
||||
OP_SHL,/* A B C R(A) := RK(B) << RK(C) */
|
||||
OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */
|
||||
OP_UNM,/* A B R(A) := -R(B) */
|
||||
OP_BNOT,/* A B R(A) := ~R(B) */
|
||||
OP_NOT,/* A B R(A) := not R(B) */
|
||||
OP_LEN,/* A B R(A) := length of R(B) */
|
||||
|
||||
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
|
||||
|
||||
OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
||||
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||
|
||||
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
|
||||
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||
|
||||
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
|
||||
OP_FORLOOP,/* A sBx R(A)+=R(A+2);
|
||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
||||
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
|
||||
OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
|
||||
|
||||
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
|
||||
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
|
||||
|
||||
OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
|
||||
|
||||
OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
|
||||
} OpCode;
|
||||
|
||||
|
||||
#endif
|
@ -1,47 +0,0 @@
|
||||
move=moves value from a register to a registers
|
||||
loadk=loads a constant value
|
||||
loadkx=loads an extended constant value
|
||||
loadbool=loads a bool value
|
||||
loadnil=loads nil
|
||||
getupval=gets an upvalue
|
||||
gettabup=gets a value from a tabular upvalue
|
||||
gettable=gets a value from a table
|
||||
setupval=sets an upvalue
|
||||
settabup=sets a value from a tabular upvalue
|
||||
settable=sets a value from a table
|
||||
newtable=creates a new table
|
||||
self=gets a value from the table and saves the table
|
||||
add=adds two registers
|
||||
sub=subtracts two registers
|
||||
mul=multiplies two register
|
||||
mod=modulo of two registers
|
||||
pow=exponentiates two registers
|
||||
div=division of two registers
|
||||
idiv=integer division of two registers
|
||||
band=boolean and of two registers
|
||||
bor=boolean or of two registers
|
||||
bxor=boolean xor of two registers
|
||||
shl=shift left of two registers
|
||||
shr=shift right of two registers
|
||||
unm=negates a register
|
||||
bnot=boolean not of a registers
|
||||
not=not of a registers
|
||||
len=length of a registers
|
||||
concat=concat of multiple registers
|
||||
jmp=relative jump
|
||||
eq=skip if not equals
|
||||
lt=skip if lower than
|
||||
le=skip if lower equals
|
||||
test=skip if register equals to value
|
||||
testset=set if register equal to value
|
||||
call=calls a function
|
||||
tailcall=calls a function and returns
|
||||
return=return of a function
|
||||
forloop=for loop header
|
||||
forprep=prepares a for loop
|
||||
tforcall=calls an iterator function
|
||||
tforloop=generic for loop head
|
||||
setlist=sets multiple consecutive fields of a table
|
||||
closure=creates an instance of a function
|
||||
vararg=copies a variable number of arguments into registers
|
||||
extraarg=an extra large argument for loadk
|
@ -17,7 +17,7 @@ ARCHS+=x86_as.mk x86_nz.mk cris_gnu.mk vax.mk
|
||||
ARCHS+=ppc_gnu.mk ppc_cs.mk x86_udis.mk xap.mk x86_nasm.mk avr.mk
|
||||
ARCHS+=sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk
|
||||
ARCHS+=6502.mk h8300.mk cr16.mk v850.mk spc700.mk propeller.mk msp430.mk i4004.mk
|
||||
ARCHS+=lh5801.mk v810.mk mcs96.mk lm32.mk lua53.mk
|
||||
ARCHS+=lh5801.mk v810.mk mcs96.mk lm32.mk
|
||||
ARCHS+=riscv.mk rsp.mk
|
||||
include $(ARCHS)
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
/* radare - LGPL - Copyright 2012-2013 - pancake */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "../arch/lua53/lua53.c"
|
||||
|
||||
static int do_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
return op->size = lua53dissasm (op, buf, len);
|
||||
}
|
||||
|
||||
static int do_assemble(RAsm *a, RAsmOp *op, const char *buf) {
|
||||
return op->size = lua53asm (op, buf);
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_lua53 = {
|
||||
.name = "lua53",
|
||||
.desc = "Lua 5.3 VM assembly plugin",
|
||||
.license = "MIT",
|
||||
.arch = "lua53",
|
||||
.bits = 32,
|
||||
.endian = R_SYS_ENDIAN_LITTLE,
|
||||
.disassemble = &do_disassemble,
|
||||
.assemble = &do_assemble,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_lua53,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
@ -1,11 +0,0 @@
|
||||
OBJ_LUA53=asm_lua53.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_LUA53}
|
||||
TARGET_LUA53=asm_lua53.${EXT_SO}
|
||||
|
||||
ifeq ($(WITHPIC),1)
|
||||
ALL_TARGETS+=${TARGET_LUA53}
|
||||
|
||||
${TARGET_LUA53}: ${OBJ_LUA53}
|
||||
${CC} $(call libname,asm_lua53) ${LDFLAGS} ${CFLAGS} -o ${TARGET_LUA53} ${OBJ_LUA53}
|
||||
endif
|
@ -14,7 +14,7 @@ FORMATS=any.mk elf.mk elf64.mk pe.mk pe64.mk te.mk mach0.mk
|
||||
FORMATS+=bios.mk mach064.mk fatmach0.mk dyldcache.mk java.mk
|
||||
FORMATS+=dex.mk fs.mk ningb.mk coff.mk ningba.mk xbe.mk zimg.mk
|
||||
FORMATS+=omf.mk cgc.mk dol.mk nes.mk mbn.mk psxexe.mk spc700.mk
|
||||
FORMATS+=vsf.mk nin3ds.mk xtr_dyldcache.mk bflt.mk lua53.mk
|
||||
FORMATS+=vsf.mk nin3ds.mk xtr_dyldcache.mk bflt.mk
|
||||
include $(FORMATS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
@ -1,329 +0,0 @@
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_bin.h>
|
||||
|
||||
#include "../../anal/arch/lua53/lua53_parser.c"
|
||||
|
||||
|
||||
static bool check_bytes(const ut8 *buf, ut64 length);
|
||||
|
||||
static int init(void *user) {
|
||||
Dprintf ("Init\n");
|
||||
return 0;
|
||||
}
|
||||
static int finit(void *user) {
|
||||
Dprintf ("FInit\n");
|
||||
if(lua53_data.functionList){
|
||||
r_list_free (lua53_data.functionList);
|
||||
lua53_data.functionList = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static bool load(RBinFile *arch){
|
||||
Dprintf ("Load\n");
|
||||
const ut8 *bytes = arch? r_buf_buffer (arch->buf): NULL;
|
||||
ut64 sz = arch? r_buf_size (arch->buf): 0;
|
||||
return check_bytes (bytes, sz);
|
||||
}
|
||||
|
||||
static bool check(RBinFile *arch) {
|
||||
Dprintf ("Check\n");
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
return check_bytes (bytes, sz);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool check_bytes(const ut8 *buf, ut64 length) {
|
||||
ParseStruct parseStruct;
|
||||
ut64 parsedbytes = lua53parseHeader (buf,0,length,&parseStruct);
|
||||
if(parsedbytes)
|
||||
Dprintf ( "It is a Lua Binary!!!\n");
|
||||
return parsedbytes != 0;
|
||||
}
|
||||
|
||||
static void addSection (RList *list, const char *name, ut64 addr, ut32 size, bool isFunc) {
|
||||
RBinSection *binSection = R_NEW0 (RBinSection);
|
||||
if (!binSection) return;
|
||||
|
||||
strcpy (binSection->name, name);
|
||||
|
||||
binSection->vaddr = binSection->paddr = addr;
|
||||
binSection->size = binSection->vsize = size;
|
||||
binSection->add = true;
|
||||
binSection->is_data = false;
|
||||
binSection->bits = isFunc ? 8*lua53_data.instructionSize : 8;
|
||||
binSection->has_strings = !isFunc;
|
||||
binSection->arch = strdup("lua53");
|
||||
if(isFunc){
|
||||
binSection->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP;
|
||||
}else
|
||||
binSection->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP;
|
||||
|
||||
r_list_append (list, binSection);
|
||||
}
|
||||
|
||||
static void addSections (LuaFunction* func, ParseStruct* parseStruct){
|
||||
|
||||
char* string;
|
||||
if(func->name_size == 0 || func->name_ptr == 0){
|
||||
string = malloc (11);
|
||||
sprintf (string,"0x%"PFMT64x,func->offset);
|
||||
}else{
|
||||
string = malloc (func->name_size + 1);
|
||||
memcpy(string,func->name_ptr,func->name_size);
|
||||
string[func->name_size] = '\0';
|
||||
}
|
||||
|
||||
char string_buffer[R_BIN_SIZEOF_STRINGS + 1];
|
||||
|
||||
sprintf (string_buffer,"header.%s",string);
|
||||
addSection (parseStruct->data,string_buffer,func->offset,func->code_offset - func->offset, false);
|
||||
|
||||
sprintf (string_buffer,"code.%s",string);
|
||||
addSection (parseStruct->data,string_buffer,func->code_offset,func->const_offset - func->code_offset, true);//code section also holds codesize
|
||||
|
||||
sprintf (string_buffer,"consts.%s",string);
|
||||
addSection (parseStruct->data,string_buffer,func->const_offset,func->upvalue_offset - func->const_offset, false);
|
||||
|
||||
sprintf (string_buffer,"upvalues.%s",string);
|
||||
addSection (parseStruct->data,string_buffer,func->upvalue_offset,func->protos_offset - func->upvalue_offset, false);
|
||||
|
||||
sprintf (string_buffer,"debuginfo.%s",string);
|
||||
addSection (parseStruct->data,string_buffer,func->debug_offset,func->offset + func->size - func->debug_offset, false);
|
||||
|
||||
r_str_free (string);
|
||||
}
|
||||
static RList* sections (RBinFile *arch) {
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
|
||||
Dprintf ("Sections\n");
|
||||
|
||||
ParseStruct parseStruct;
|
||||
memset (&parseStruct,0,sizeof(parseStruct));
|
||||
parseStruct.onFunction = addSections;
|
||||
|
||||
parseStruct.data = r_list_newf ((RListFree)free);
|
||||
if(!parseStruct.data)
|
||||
return NULL;
|
||||
|
||||
ut64 headersize = 4 + 1 + 1 + 6 + 5 + bytes[15] + bytes[16] + 1;//header + version + format + stringterminators + sizes + integer + number + upvalues
|
||||
addSection (parseStruct.data,"lua-header",0,headersize, false);
|
||||
|
||||
//parse functions
|
||||
lua53parseFunction (bytes,headersize,sz,0,&parseStruct);
|
||||
|
||||
Dprintf ("End Section\n");
|
||||
return parseStruct.data;
|
||||
}
|
||||
|
||||
static void addString(const ut8 *buf, ut64 offset, ut64 length,ParseStruct* parseStruct){
|
||||
RBinString* binstring = R_NEW0 (RBinString);
|
||||
|
||||
if(binstring == NULL)
|
||||
return;
|
||||
|
||||
binstring->string = r_str_newlen ((char*)buf + offset,length);
|
||||
binstring->vaddr = binstring->paddr = offset;
|
||||
binstring->ordinal = 0;
|
||||
binstring->size = length;
|
||||
binstring->length = length;
|
||||
r_list_append (parseStruct->data, binstring);
|
||||
}
|
||||
|
||||
static void addSymbol (RList *list, char *name, ut64 addr, ut32 size, const char* type) {
|
||||
|
||||
RBinSymbol* binSymbol = R_NEW0 (RBinSymbol);
|
||||
if(binSymbol == NULL)
|
||||
return;
|
||||
|
||||
binSymbol->name = strdup (name);
|
||||
|
||||
binSymbol->vaddr = binSymbol->paddr = addr;
|
||||
binSymbol->size = size;
|
||||
binSymbol->ordinal = 0;
|
||||
binSymbol->type = type;
|
||||
r_list_append (list, binSymbol);
|
||||
}
|
||||
static void handleFuncSymbol (LuaFunction* func, ParseStruct* parseStruct){
|
||||
|
||||
RBinSymbol* binSymbol = R_NEW0 (RBinSymbol);
|
||||
|
||||
if(binSymbol == NULL)
|
||||
return;
|
||||
|
||||
char* string;
|
||||
if(!func->name_ptr || !func->name_size){
|
||||
string = malloc (11);
|
||||
sprintf (string,"0x%"PFMT64x,func->offset);
|
||||
}else{
|
||||
string = malloc (func->name_size + 1);
|
||||
memcpy(string,func->name_ptr,func->name_size);
|
||||
int i;
|
||||
for(i = 0; i < func->name_size;i++)
|
||||
if(string[i] == '@')
|
||||
string[i] = '_';
|
||||
string[func->name_size] = '\0';
|
||||
}
|
||||
char string_buffer[R_BIN_SIZEOF_STRINGS + 1];
|
||||
|
||||
|
||||
|
||||
sprintf (string_buffer,"lineDefined.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset - 3 - 2*lua53_data.intSize,lua53_data.intSize,"NUM");
|
||||
sprintf (string_buffer,"lastLineDefined.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset - 3 - lua53_data.intSize,lua53_data.intSize,"NUM");
|
||||
sprintf (string_buffer,"numParams.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset - 3,1,"NUM");
|
||||
sprintf (string_buffer,"isVarArg.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset - 2,1,"BOOL");
|
||||
sprintf (string_buffer,"maxStackSize.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset - 1,1,"BOOL");
|
||||
|
||||
sprintf (string_buffer,"codesize.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset,lua53_data.intSize,"NUM");
|
||||
|
||||
sprintf (string_buffer,"func.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->code_offset + lua53_data.intSize,lua53_data.instructionSize*func->code_size,"FUNC");
|
||||
|
||||
sprintf (string_buffer,"constsize.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->const_offset,lua53_data.intSize,"NUM");
|
||||
|
||||
sprintf (string_buffer,"upvaluesize.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->upvalue_offset,lua53_data.intSize,"NUM");
|
||||
|
||||
sprintf (string_buffer,"prototypesize.%s",string);
|
||||
addSymbol (parseStruct->data,string_buffer,func->protos_offset,lua53_data.intSize,"NUM");
|
||||
|
||||
r_str_free (string);
|
||||
}
|
||||
|
||||
|
||||
static RList* strings(RBinFile *arch) {
|
||||
|
||||
Dprintf ("Strings\n");
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
|
||||
ut64 headersize = 4 + 1 + 1 + 6 + 5 + bytes[15] + bytes[16] + 1;//header + version + format + stringterminators + sizes + integer + number + upvalues
|
||||
|
||||
ParseStruct parseStruct;
|
||||
memset (&parseStruct,0,sizeof (parseStruct));
|
||||
parseStruct.onString = addString;
|
||||
|
||||
parseStruct.data = r_list_new ();
|
||||
if(!parseStruct.data)
|
||||
return NULL;
|
||||
|
||||
lua53parseFunction (bytes,headersize,sz,0,&parseStruct);
|
||||
|
||||
Dprintf ("End Strings\n");
|
||||
return parseStruct.data;
|
||||
}
|
||||
static RList* symbols(RBinFile *arch) {
|
||||
Dprintf ("Symbols\n");
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
|
||||
ut64 headersize = 4 + 1 + 1 + 6 + 5 + bytes[15] + bytes[16] + 1;//header + version + format + stringterminators + sizes + integer + number + upvalues
|
||||
|
||||
ParseStruct parseStruct;
|
||||
memset (&parseStruct,0,sizeof(parseStruct));
|
||||
parseStruct.onFunction = handleFuncSymbol;
|
||||
parseStruct.data = NULL;
|
||||
|
||||
parseStruct.data = r_list_new ();
|
||||
if(!parseStruct.data)
|
||||
return NULL;
|
||||
|
||||
addSymbol (parseStruct.data,"lua-header",0,4,"NOTYPE");
|
||||
addSymbol (parseStruct.data,"lua-version",4,1,"NOTYPE");
|
||||
addSymbol (parseStruct.data,"lua-format",5,1,"NOTYPE");
|
||||
addSymbol (parseStruct.data,"stringterminators",6,6,"NOTYPE");
|
||||
addSymbol (parseStruct.data,"int-size",12,1,"NUM");
|
||||
addSymbol (parseStruct.data,"size-size",13,1,"NUM");
|
||||
addSymbol (parseStruct.data,"instruction-size",14,1,"NUM");
|
||||
addSymbol (parseStruct.data,"lua-int-size",15,1,"NUM");
|
||||
addSymbol (parseStruct.data,"lua-number-size",16,1,"NUM");
|
||||
addSymbol (parseStruct.data,"check-int",17,bytes[15],"NUM");
|
||||
addSymbol (parseStruct.data,"check-number",17 + bytes[15],bytes[16],"FLOAT");
|
||||
addSymbol (parseStruct.data,"upvalues",17 + bytes[15] + bytes[16],1,"NUM");
|
||||
|
||||
lua53parseFunction (bytes,headersize,sz,0,&parseStruct);
|
||||
|
||||
Dprintf ("End Symbols\n");
|
||||
return parseStruct.data;
|
||||
}
|
||||
static RBinInfo* info(RBinFile *arch) {
|
||||
RBinInfo *ret = NULL;
|
||||
if (!(ret = R_NEW0 (RBinInfo)))
|
||||
return NULL;
|
||||
ret->file = strdup (arch->file);
|
||||
ret->type = strdup ("lua53");
|
||||
ret->os = strdup ("any");
|
||||
ret->machine = strdup ("LUA 5.3 VM");
|
||||
ret->arch = strdup ("lua53");
|
||||
ret->bits = lua53_data.instructionSize * 8;
|
||||
ret->has_va = 1;
|
||||
ret->big_endian = 0;
|
||||
return ret;
|
||||
}
|
||||
static void addEntry (LuaFunction* func, ParseStruct* parseStruct){
|
||||
|
||||
if(func->parent_func == NULL){
|
||||
RBinAddr *ptr = NULL;
|
||||
if ((ptr = R_NEW0 (RBinAddr))) {
|
||||
ptr->paddr = ptr->vaddr = func->code_offset + lua53_data.intSize;
|
||||
r_list_append (parseStruct->data, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
static RList* entries(RBinFile *arch) {
|
||||
Dprintf ("Entries\n");
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
|
||||
ut64 headersize = 4 + 1 + 1 + 6 + 5 + bytes[15] + bytes[16] + 1;//header + version + format + stringterminators + sizes + integer + number + upvalues
|
||||
|
||||
ParseStruct parseStruct;
|
||||
memset (&parseStruct,0,sizeof(parseStruct));
|
||||
parseStruct.onFunction = addEntry;
|
||||
parseStruct.data = NULL;
|
||||
|
||||
parseStruct.data = r_list_new ();
|
||||
if(!parseStruct.data)
|
||||
return NULL;
|
||||
|
||||
lua53parseFunction (bytes,headersize,sz,0,&parseStruct);
|
||||
|
||||
Dprintf ("End Entries\n");
|
||||
return parseStruct.data;
|
||||
}
|
||||
|
||||
RBinPlugin r_bin_plugin_lua53 = {
|
||||
.name = "lua53",
|
||||
.desc = "LUA 5.3 bin plugin",
|
||||
.license = "MIT",
|
||||
.init = &init,
|
||||
.fini = &finit,
|
||||
.load = &load,
|
||||
.sections = §ions,
|
||||
.check = &check,
|
||||
.check_bytes = &check_bytes,
|
||||
.symbols = &symbols,
|
||||
.strings = &strings,
|
||||
.info = &info,
|
||||
.entries = &entries,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_lua53,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
OBJ_LUA53=bin_lua53.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_LUA53}
|
||||
TARGET_LUA53=bin_lua53.${EXT_SO}
|
||||
|
||||
ifeq (${WITHPIC},1)
|
||||
ALL_TARGETS+=${TARGET_LUA53}
|
||||
|
||||
${TARGET_LUA53}: ${OBJ_LUA53}
|
||||
-${CC} $(call libname,bin_lua53) -shared ${CFLAGS} \
|
||||
$(OBJ_LUA53) $(LINK) $(LDFLAGS)
|
||||
endif
|
@ -1625,7 +1625,6 @@ extern RAnalPlugin r_anal_plugin_i4004;
|
||||
extern RAnalPlugin r_anal_plugin_xtensa;
|
||||
extern RAnalPlugin r_anal_plugin_pic18c;
|
||||
extern RAnalPlugin r_anal_plugin_rsp;
|
||||
extern RAnalPlugin r_anal_plugin_lua53;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -246,7 +246,6 @@ extern RAsmPlugin r_asm_plugin_tricore;
|
||||
extern RAsmPlugin r_asm_plugin_pic18c;
|
||||
extern RAsmPlugin r_asm_plugin_rsp;
|
||||
extern RAsmPlugin r_asm_plugin_wasm;
|
||||
extern RAsmPlugin r_asm_plugin_lua53;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -358,7 +358,7 @@ typedef struct r_bin_section_t {
|
||||
int bits;
|
||||
bool has_strings;
|
||||
bool add; // indicates when you want to add the section to io `S` command
|
||||
bool is_data;
|
||||
bool is_data;
|
||||
} RBinSection;
|
||||
|
||||
typedef struct r_bin_class_t {
|
||||
@ -677,7 +677,6 @@ extern RBinPlugin r_bin_plugin_dyldcache;
|
||||
extern RBinPlugin r_bin_plugin_avr;
|
||||
extern RBinPlugin r_bin_plugin_menuet;
|
||||
extern RBinPlugin r_bin_plugin_wasm;
|
||||
extern RBinPlugin r_bin_plugin_lua53;
|
||||
extern RBinPlugin r_bin_plugin_nro;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -13,7 +13,6 @@ anal.gb
|
||||
anal.h8300
|
||||
anal.i8080
|
||||
anal.java
|
||||
anal.lua53
|
||||
anal.m68k_cs
|
||||
anal.xtensa
|
||||
anal.malbolge
|
||||
@ -62,7 +61,6 @@ asm.hppa_gnu
|
||||
asm.i4004
|
||||
asm.i8080
|
||||
asm.java
|
||||
asm.lua53
|
||||
asm.lm32
|
||||
asm.tricore
|
||||
asm.xtensa
|
||||
@ -118,7 +116,6 @@ bin.elf
|
||||
bin.elf64
|
||||
bin.fs
|
||||
bin.java
|
||||
bin.lua53
|
||||
bin.menuet
|
||||
bin.mach0
|
||||
bin.mach064
|
||||
|
Loading…
Reference in New Issue
Block a user