int efile_may_openfile(Efile_error* errInfo, char *name) { struct stat statbuf; /* Information about the file */ int result; result = stat(name, &statbuf); if (!check_error(result, errInfo)) return 0; if (!ISREG(statbuf)) { errno = EISDIR; return check_error(-1, errInfo); } return 1; }
// decodes operand static void decopr(x86_opr *out, decstruct *d, u4 o) { u4 t = OPRTOK(o); if(ISREG(t)) { isreg: if(t < ES) { // gpr int s = GETTYPE(o); if(!d->opr32 || s == WORD) t += AX-eAX; // 16-bit register else if(s == BYTE) t += AL-eAX; // 8-bit register } out->tok = X86_OREG; out->reg = t; } else if(ISMODRM(t)) { if(ISMODRM_REG(t) || R == t || (M != t && MOD(d->modrm) == 3)) { o = ISMODRM_REG(t) ? REG(d->modrm) : RM(d->modrm); if(S == t) o += ES; // segment register else if(T == t) o += TR0; // test register else if(D == t) o += DR0; // debug register else o += eAX; t = o; goto isreg; } // else it is a memory reference memcpy(&out->mem, &d->mem, sizeof(d->mem)); out->tok = X86_OMEM; out->mem.size = GETTYPE(o); } else switch(t) { case I: out->tok = X86_OVAL; memcpy(&out->val, &d->imm, sizeof(d->imm)); break; case J: out->tok = X86_OVAL; memcpy(&out->val, &d->imm, sizeof(d->imm)); out->val.sign = 1; break; case O: case A: // direct address or ds:offset out->tok = X86_OMEM; if(t == A) out->mem.disp.val = LSB16(d->q)*16; else out->mem.seg = DS; // offset in ds d->q += 2; if(d->adr32) { out->mem.disp.val += LSB32(d->q); d->q += 4; } else { out->mem.disp.val += LSB16(d->q); d->q += 2; } if(!(out->mem.size = GETTYPE(o))) out->mem.size = d->opr32 ? DWORD : WORD; break; case X: case Y: // string instruction break; default: if(t >= CONST_0 && t <= CONST_LAST) { out->tok = X86_OVAL; out->val.val = t-CONST_0; out->val.sign = 0; out->val.size = GETTYPE(o); } else out->tok = X86_ONON; break; } return; }
int efile_openfile(Efile_error* errInfo, /* Where to return error codes. */ char* name, /* Name of directory to open. */ int flags, /* Flags to user for opening. */ int* pfd, /* Where to store the file descriptor. */ Sint64 *pSize) /* Where to store the size of the file. */ { struct stat statbuf; int fd; int mode; /* Open mode. */ if (stat(name, &statbuf) < 0) { /* statbuf is undefined: if the caller depends on it, i.e. invoke_read_file(), fail the call immediately */ if (pSize && flags == EFILE_MODE_READ) return check_error(-1, errInfo); } else if (!ISREG(statbuf)) { /* * For UNIX only, here is some ugly code to allow * /dev/null to be opened as a file. * * Assumption: The i-node number for /dev/null cannot be zero. */ static ino_t dev_null_ino = 0; if (dev_null_ino == 0) { struct stat nullstatbuf; if (stat("/dev/null", &nullstatbuf) >= 0) { dev_null_ino = nullstatbuf.st_ino; } } if (!(dev_null_ino && statbuf.st_ino == dev_null_ino)) { errno = EISDIR; return check_error(-1, errInfo); } } switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) { case EFILE_MODE_READ: mode = O_RDONLY; break; case EFILE_MODE_WRITE: if (flags & EFILE_NO_TRUNCATE) mode = O_WRONLY | O_CREAT; else mode = O_WRONLY | O_CREAT | O_TRUNC; break; case EFILE_MODE_READ_WRITE: mode = O_RDWR | O_CREAT; break; default: errno = EINVAL; return check_error(-1, errInfo); } if (flags & EFILE_MODE_APPEND) { mode &= ~O_TRUNC; mode |= O_APPEND; } if (flags & EFILE_MODE_EXCL) { mode |= O_EXCL; } if (flags & EFILE_MODE_SYNC) { #ifdef O_SYNC mode |= O_SYNC; #else errno = ENOTSUP; return check_error(-1, errInfo); #endif } fd = open(name, mode, FILE_MODE); if (!check_error(fd, errInfo)) return 0; *pfd = fd; if (pSize) { *pSize = statbuf.st_size; } return 1; }
static void anop32 (RAnalOp *op, cs_insn *insn) { ut64 addr = op->addr; int i; switch (insn->id) { case ARM_INS_NOP: op->type = R_ANAL_OP_TYPE_NOP; break; case ARM_INS_POP: case ARM_INS_LDM: op->type = R_ANAL_OP_TYPE_POP; for (i = 0; i < insn->detail->arm.op_count; i++) { if (insn->detail->arm.operands[i].type == ARM_OP_REG && insn->detail->arm.operands[i].reg == ARM_REG_PC) { if (insn->detail->arm.cc == ARM_CC_AL) op->type = R_ANAL_OP_TYPE_RET; else op->type = R_ANAL_OP_TYPE_CRET; break; } } break; case ARM_INS_SUB: op->type = R_ANAL_OP_TYPE_SUB; if (ISREG(0)) { if (REGID(0) == ARM_REG_SP) { // 0x00008254 10d04de2 sub sp, sp, 0x10 op->stackop = R_ANAL_STACK_INC; op->stackptr = IMM (2); } } break; case ARM_INS_ADD: op->type = R_ANAL_OP_TYPE_ADD; if (REGID(1)==ARM_REG_PC) { op->ptr = addr + 8 + IMM(2); op->refptr = 0; } break; case ARM_INS_MOV: case ARM_INS_MOVS: case ARM_INS_MOVT: case ARM_INS_MOVW: case ARM_INS_VMOVL: case ARM_INS_VMOVN: case ARM_INS_VQMOVUN: case ARM_INS_VQMOVN: op->type = R_ANAL_OP_TYPE_MOV; break; case ARM_INS_AND: op->type = R_ANAL_OP_TYPE_AND; break; case ARM_INS_CMP: case ARM_INS_TST: op->type = R_ANAL_OP_TYPE_CMP; break; case ARM_INS_ROR: case ARM_INS_ORN: case ARM_INS_LSL: case ARM_INS_LSR: break; //case ARM_INS_POP: case ARM_INS_PUSH: case ARM64_INS_STRB: case ARM_INS_STR: op->type = R_ANAL_OP_TYPE_STORE; // 0x00008160 04202de5 str r2, [sp, -4]! // 0x000082a0 28000be5 str r0, [fp, -0x28] if (REGBASE(1) == ARM_REG_FP) { op->stackop = R_ANAL_STACK_SET; op->stackptr = 0; op->ptr = MEMDISP(1); } break; case ARM_INS_LDR: case ARM_INS_LDRD: case ARM_INS_LDRB: // 0x000082a8 28301be5 ldr r3, [fp, -0x28] if (insn->detail->arm.operands[0].reg == ARM_REG_PC) { op->type = R_ANAL_OP_TYPE_UJMP; } else { op->type = R_ANAL_OP_TYPE_LOAD; } if (REGBASE(1) == ARM_REG_FP) { op->stackop = R_ANAL_STACK_GET; op->stackptr = 0; op->ptr = MEMDISP(1); } break; case ARM_INS_BL: case ARM_INS_BLX: op->type = R_ANAL_OP_TYPE_CALL; op->jump = IMM(0); break; case ARM_INS_B: case ARM_INS_BX: case ARM_INS_BXJ: // BX LR == RET if (insn->detail->arm.operands[0].reg == ARM_REG_LR) { op->type = R_ANAL_OP_TYPE_RET; } else if (insn->detail->arm.cc) { op->type = R_ANAL_OP_TYPE_CJMP; op->jump = (ut64) (ut32)IMM(0); op->fail = addr+op->size; } else { op->type = R_ANAL_OP_TYPE_JMP; op->jump = IMM(0); } break; default: break; } }