From 625399774ccda894e22e12f9782376bacb794fd3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 5 May 2020 02:34:51 +0200 Subject: [PATCH] X64 base regs (#1166) * x86: setup FS & GS base * Fixed base register writes for x64, removed then for x16/x32 (the don't exist there?) * FS reg comes before GS so the base regs do so, too * added shebang to const_generator.py * Added base regs to and added 'all' support to const_generator Co-authored-by: naq --- bindings/const_generator.py | 16 ++++++++--- bindings/dotnet/UnicornManaged/Const/X86.fs | 4 ++- bindings/go/unicorn/x86_const.go | 4 ++- bindings/java/unicorn/X86Const.java | 4 ++- bindings/pascal/unicorn/X86Const.pas | 4 ++- bindings/python/unicorn/x86_const.py | 4 ++- .../lib/unicorn_engine/x86_const.rb | 4 ++- include/unicorn/x86.h | 2 ++ qemu/target-i386/unicorn.c | 27 +++++++++++++++++++ 9 files changed, 59 insertions(+), 10 deletions(-) diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 2d11505a..daa18f0d 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Unicorn Engine # By Dang Hoang Vu, 2013 from __future__ import print_function @@ -118,7 +119,8 @@ def gen(lang): outfile.write((templ['header'] % (prefix)).encode("utf-8")) if target == 'unicorn.h': prefix = '' - lines = open(os.path.join(INCL_DIR, target)).readlines() + with open(os.path.join(INCL_DIR, target)) as f: + lines = f.readlines() previous = {} count = 0 @@ -185,12 +187,18 @@ def gen(lang): def main(): lang = sys.argv[1] - if not lang in template: - raise RuntimeError("Unsupported binding %s" % lang) - gen(sys.argv[1]) + if lang == "all": + for lang in template.keys(): + print("Generating constants for {}".format(lang)) + gen(lang) + else: + if not lang in template: + raise RuntimeError("Unsupported binding %s" % lang) + gen(lang) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage:", sys.argv[0], " ") + print("Supported: {}".format(["all"] + [x for x in template.keys()])) sys.exit(1) main() diff --git a/bindings/dotnet/UnicornManaged/Const/X86.fs b/bindings/dotnet/UnicornManaged/Const/X86.fs index 5112ae2d..ad16a84f 100644 --- a/bindings/dotnet/UnicornManaged/Const/X86.fs +++ b/bindings/dotnet/UnicornManaged/Const/X86.fs @@ -259,7 +259,9 @@ module X86 = let UC_X86_REG_FPTAG = 247 let UC_X86_REG_MSR = 248 let UC_X86_REG_MXCSR = 249 - let UC_X86_REG_ENDING = 250 + let UC_X86_REG_FS_BASE = 250 + let UC_X86_REG_GS_BASE = 251 + let UC_X86_REG_ENDING = 252 // X86 instructions diff --git a/bindings/go/unicorn/x86_const.go b/bindings/go/unicorn/x86_const.go index 847efe2c..33899a61 100644 --- a/bindings/go/unicorn/x86_const.go +++ b/bindings/go/unicorn/x86_const.go @@ -254,7 +254,9 @@ const ( X86_REG_FPTAG = 247 X86_REG_MSR = 248 X86_REG_MXCSR = 249 - X86_REG_ENDING = 250 + X86_REG_FS_BASE = 250 + X86_REG_GS_BASE = 251 + X86_REG_ENDING = 252 // X86 instructions diff --git a/bindings/java/unicorn/X86Const.java b/bindings/java/unicorn/X86Const.java index 2f1f2930..d7a358bf 100644 --- a/bindings/java/unicorn/X86Const.java +++ b/bindings/java/unicorn/X86Const.java @@ -256,7 +256,9 @@ public interface X86Const { public static final int UC_X86_REG_FPTAG = 247; public static final int UC_X86_REG_MSR = 248; public static final int UC_X86_REG_MXCSR = 249; - public static final int UC_X86_REG_ENDING = 250; + public static final int UC_X86_REG_FS_BASE = 250; + public static final int UC_X86_REG_GS_BASE = 251; + public static final int UC_X86_REG_ENDING = 252; // X86 instructions diff --git a/bindings/pascal/unicorn/X86Const.pas b/bindings/pascal/unicorn/X86Const.pas index e52b499c..27994b6c 100644 --- a/bindings/pascal/unicorn/X86Const.pas +++ b/bindings/pascal/unicorn/X86Const.pas @@ -257,7 +257,9 @@ const UC_X86_REG_FPTAG = 247; UC_X86_REG_MSR = 248; UC_X86_REG_MXCSR = 249; - UC_X86_REG_ENDING = 250; + UC_X86_REG_FS_BASE = 250; + UC_X86_REG_GS_BASE = 251; + UC_X86_REG_ENDING = 252; // X86 instructions diff --git a/bindings/python/unicorn/x86_const.py b/bindings/python/unicorn/x86_const.py index 154f70a5..9c0fbadf 100644 --- a/bindings/python/unicorn/x86_const.py +++ b/bindings/python/unicorn/x86_const.py @@ -252,7 +252,9 @@ UC_X86_REG_FPCW = 246 UC_X86_REG_FPTAG = 247 UC_X86_REG_MSR = 248 UC_X86_REG_MXCSR = 249 -UC_X86_REG_ENDING = 250 +UC_X86_REG_FS_BASE = 250 +UC_X86_REG_GS_BASE = 251 +UC_X86_REG_ENDING = 252 # X86 instructions diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/x86_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/x86_const.rb index e156236f..8063eec5 100644 --- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/x86_const.rb +++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/x86_const.rb @@ -254,7 +254,9 @@ module UnicornEngine UC_X86_REG_FPTAG = 247 UC_X86_REG_MSR = 248 UC_X86_REG_MXCSR = 249 - UC_X86_REG_ENDING = 250 + UC_X86_REG_FS_BASE = 250 + UC_X86_REG_GS_BASE = 251 + UC_X86_REG_ENDING = 252 # X86 instructions diff --git a/include/unicorn/x86.h b/include/unicorn/x86.h index 235dac6a..cd2c66db 100644 --- a/include/unicorn/x86.h +++ b/include/unicorn/x86.h @@ -89,6 +89,8 @@ typedef enum uc_x86_reg { UC_X86_REG_FPTAG, UC_X86_REG_MSR, // Model-Specific Register UC_X86_REG_MXCSR, + UC_X86_REG_FS_BASE, // Base regs for x86_64 + UC_X86_REG_GS_BASE, UC_X86_REG_ENDING // <-- mark the end of the list of registers } uc_x86_reg; diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 242261fb..ff7c37b1 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -340,6 +340,9 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun case UC_X86_REG_GS: *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].selector; continue; + case UC_X86_REG_FS_BASE: + *(uint32_t *)value = (uint32_t)X86_CPU(uc, mycpu)->env.segs[R_FS].base; + continue; } // fall-thru case UC_MODE_32: @@ -488,6 +491,9 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun case UC_X86_REG_MXCSR: *(uint32_t *)value = X86_CPU(uc, mycpu)->env.mxcsr; break; + case UC_X86_REG_FS_BASE: + *(uint32_t *)value = (uint32_t)X86_CPU(uc, mycpu)->env.segs[R_FS].base; + break; } break; @@ -788,6 +794,12 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun dst[1] = reg->_d[1]; break; } + case UC_X86_REG_FS_BASE: + *(uint64_t *)value = (uint64_t)X86_CPU(uc, mycpu)->env.segs[R_FS].base; + break; + case UC_X86_REG_GS_BASE: + *(uint64_t *)value = (uint64_t)X86_CPU(uc, mycpu)->env.segs[R_GS].base; + break; } break; #endif @@ -1089,6 +1101,15 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i case UC_X86_REG_MXCSR: cpu_set_mxcsr(&X86_CPU(uc, mycpu)->env, *(uint32_t *)value); break; + /* + // Don't think base registers are a "thing" on x86 + case UC_X86_REG_FS_BASE: + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint32_t *)value; + continue; + case UC_X86_REG_GS_BASE: + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint32_t *)value; + continue; + */ } break; @@ -1407,6 +1428,12 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i reg->_d[1] = src[1]; break; } + case UC_X86_REG_FS_BASE: + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint64_t *)value; + continue; + case UC_X86_REG_GS_BASE: + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint64_t *)value; + continue; } break; #endif