Skip to content

Commit a9cbff2

Browse files
authored
Fix parsing of unsigned 64-bit constants (#36)
* fix typo in error msg (invald -> invalid) * replace stoll by stoull: former cannot deal with (unsigned) constants such as 0xffffffffffffffff but instead causes a crash. The implicit assumption here was that large values must be signed values (and should be passed as -1 instead of 0xff..ff). Using stoull fixes this problem and allows the code to work with both unsigned and signed constants * add il parser for 64 bit and testcases to verify that the code can deal with both 0xffffffffffffffff and -1
1 parent 16f3a82 commit a9cbff2

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

libropium/compiler/il.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ bool _parse_il_cst(Arch& arch, vector<cst_t>& args, string& str, int& idx){
5858
}
5959

6060
try{
61-
cst = std::stoll(s, 0, base);
61+
cst = std::stoull(s, 0, base);
6262
// Check if cst is not too big
6363
if( arch.octets < 8 && (cst >= (ucst_t)((ucst_t)1<<(arch.bits)))){
6464
return false;
@@ -769,7 +769,7 @@ bool _parse_il_instruction(Arch& arch, ILInstruction* instr, string& str){
769769

770770
ILInstruction::ILInstruction(Arch& arch, string str){
771771
if( !_parse_il_instruction(arch, this, str)){
772-
throw il_exception("Invald instruction string");
772+
throw il_exception("Invalid instruction string");
773773
}
774774
}
775775

tests/test_il.cpp

+39-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace test{
148148
nb += _assert(instr.type == ILInstructionType::LOAD_CST, "Failed to parse IL Instruction");
149149
nb += _assert(instr.args[PARAM_LOADCST_DST_REG] == X86_EAX, "Failed to parse IL Instruction");
150150
nb += _assert(instr.args[PARAM_LOADCST_SRC_ADDR_OFFSET] == 0xffffffff, "Failed to parse IL Instruction");
151-
151+
152152
// aload_cst
153153
str = " edi ^= [0]";
154154
instr = ILInstruction(arch, str);
@@ -360,6 +360,43 @@ namespace test{
360360

361361
return nb;
362362
}
363+
364+
unsigned int il_parser64(){
365+
unsigned int nb = 0;
366+
ArchX64 arch;
367+
368+
// parse_il_cst should work with both unsigned and signed constants
369+
string str = " 1000( 0xffffffffffffffff, -1 )";
370+
ILInstruction instr = ILInstruction(arch, str);
371+
nb += _assert(instr.type == ILInstructionType::FUNCTION, "Failed to parse IL Instruction");
372+
nb += _assert(instr.args[PARAM_FUNCTION_ADDR] == 1000, "Failed to parse IL Instruction");
373+
nb += _assert(instr.args[PARAM_FUNCTION_ARGS+0] == (cst_t)0xffffffffffffffff, "Failed to parse IL Instruction");
374+
nb += _assert(instr.args_type[PARAM_FUNCTION_ARGS+0] == IL_FUNC_ARG_CST, "Failed to parse IL Instruction");
375+
nb += _assert(instr.args[PARAM_FUNCTION_ARGS+1] == -1, "Failed to parse IL Instruction");
376+
nb += _assert(instr.args_type[PARAM_FUNCTION_ARGS+1] == IL_FUNC_ARG_CST, "Failed to parse IL Instruction");
377+
378+
str = "rax= [0x7000000000000000]";
379+
instr = ILInstruction(arch, str);
380+
nb += _assert(instr.type == ILInstructionType::LOAD_CST, "Failed to parse IL Instruction");
381+
nb += _assert(instr.args[PARAM_LOADCST_DST_REG] == X64_RAX, "Failed to parse IL Instruction");
382+
nb += _assert(instr.args[PARAM_LOADCST_SRC_ADDR_OFFSET] == (cst_t)0x7000000000000000, "Failed to parse IL Instruction");
383+
384+
// 0xffffffffffffffff == -1
385+
str = "rdx= 0xffffffffffffffff";
386+
instr = ILInstruction(arch, str);
387+
nb += _assert(instr.type == ILInstructionType::MOV_CST, "Failed to parse IL Instruction");
388+
nb += _assert(instr.args[PARAM_MOVCST_DST_REG] == X64_RDX, "Failed to parse IL Instruction");
389+
nb += _assert(instr.args[PARAM_MOVCST_SRC_CST] == -1, "Failed to parse IL Instruction");
390+
391+
// Edge case: -0xffffffffffffffff == -(0xffffffffffffffff) == -(-1) == 1
392+
str = "rcx= -0xffffffffffffffff";
393+
instr = ILInstruction(arch, str);
394+
nb += _assert(instr.type == ILInstructionType::MOV_CST, "Failed to parse IL Instruction");
395+
nb += _assert(instr.args[PARAM_MOVCST_DST_REG] == X64_RCX, "Failed to parse IL Instruction");
396+
nb += _assert(instr.args[PARAM_MOVCST_SRC_CST] == 1, "Failed to parse IL Instruction");
397+
398+
return nb;
399+
}
363400
}
364401
}
365402

@@ -374,6 +411,7 @@ void test_il(){
374411
// Start testing
375412
cout << bold << "[" << green << "+" << def << bold << "]" << def << std::left << std::setw(34) << " Testing il module... " << std::flush;
376413
total += il_parser();
414+
total += il_parser64();
377415
// Return res
378416
cout << "\t" << total << "/" << total << green << "\t\tOK" << def << endl;
379417
}

0 commit comments

Comments
 (0)