Merge branch 'master' into mem_map_ex_cse

This commit is contained in:
Chris Eagle 2015-09-01 12:13:53 -07:00
commit 49d1fa7ebd
6 changed files with 192 additions and 2 deletions

1
.gitignore vendored
View file

@ -88,3 +88,4 @@ regress/map_write
regress/ro_mem_test regress/ro_mem_test
regress/nr_mem_test regress/nr_mem_test
regress/timeout_segfault regress/timeout_segfault
regress/rep_movsb

View file

@ -87,7 +87,7 @@ Unicorn requires few dependent packages as followings
Users are then required to enter root password to copy Unicorn into machine Users are then required to enter root password to copy Unicorn into machine
system directories. system directories.
Afterwards, run ./tests/test* to see the tests disassembling sample code. Afterwards, run ./samples/sample_all.sh to see the sample emulations.
NOTE: The core framework installed by "./make.sh install" consist of NOTE: The core framework installed by "./make.sh install" consist of

View file

@ -54,6 +54,11 @@ void x86_reg_reset(uch handle)
CPUArchState *env; CPUArchState *env;
env = first_cpu->env_ptr; env = first_cpu->env_ptr;
env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH;
env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_AES;
env->features[FEAT_8000_0001_EDX] = CPUID_EXT2_3DNOW | CPUID_EXT2_RDTSCP;
env->features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_SKINIT | CPUID_EXT3_CR8LEG;
env->features[FEAT_7_0_EBX] = CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP;
env->invalid_error = UC_ERR_OK; // no error env->invalid_error = UC_ERR_OK; // no error
memset(env->regs, 0, sizeof(env->regs)); memset(env->regs, 0, sizeof(env->regs));

View file

@ -6,6 +6,7 @@ TESTS += sigill sigill2
TESTS += block_test TESTS += block_test
TESTS += ro_mem_test nr_mem_test TESTS += ro_mem_test nr_mem_test
TESTS += timeout_segfault TESTS += timeout_segfault
TESTS += rep_movsb
all: $(TESTS) all: $(TESTS)

View file

@ -9,4 +9,4 @@ uc = Uc(UC_ARCH_X86, UC_MODE_64)
uc.mem_map(0x2000, 0x1000) uc.mem_map(0x2000, 0x1000)
# pshufb xmm0, xmm1 # pshufb xmm0, xmm1
uc.mem_write(0x2000, '660f3800c1'.decode('hex')) uc.mem_write(0x2000, '660f3800c1'.decode('hex'))
uc.emu_start(0x2000, 0) uc.emu_start(0x2000, 0x2005)

183
regress/rep_movsb.c Normal file
View file

@ -0,0 +1,183 @@
/*
rep movsb regression
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
unsigned char PROGRAM[] =
"\xbe\x00\x00\x20\x00\xbf\x00\x10\x20\x00\xb9\x14\x00\x00\x00\xf3"
"\xa4\xf4";
// total size: 18 bytes
/*
bits 32
; assumes code section at 0x100000 r-x
; assumes data section at 0x200000-0x202000, rw-
mov esi, 0x200000
mov edi, 0x201000
mov ecx, 20
rep movsb
hlt
*/
static int log_num = 1;
// callback for tracing instruction
static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) {
printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
_exit(-1);
}
switch (opcode) {
case 0xf4: //hlt
printf("# Handling HLT\n");
if (uc_emu_stop(handle) != UC_ERR_OK) {
printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
_exit(-1);
}
else {
printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++);
}
break;
default: //all others
break;
}
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uch handle, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
if (addr < 0x201000L) {
//this is actually a read, we don't write in this range
printf("not ok %d - write hook called for read of 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", log_num++, addr, size, value);
}
else {
printf("ok %d - write hook called for write of 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", log_num++, addr, size, value);
}
}
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
uc_err err;
uint8_t buf1[100], readbuf[100];
printf("# rep movsb test\n");
memset(buf1, 'A', 20);
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;
}
else {
printf("ok %d - uc_open() success\n", log_num++);
}
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(handle, 0x200000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
// fill in the data that we want to copy
if (uc_mem_write(handle, 0x200000, (uint8_t*)buf1, 20)) {
printf("not ok %d - Failed to write read buffer to memory, quit!\n", log_num++);
return 2;
}
else {
printf("ok %d - Read buffer written to memory\n", log_num++);
}
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) {
printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++);
return 4;
}
else {
printf("ok %d - Program written to memory\n", log_num++);
}
if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++);
return 5;
}
else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events only, NOT read events
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
return 6;
}
else {
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
}
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
err = uc_emu_start(handle, 0x100000, 0x101000, 0, 0);
if (err != UC_ERR_OK) {
printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err));
return 8;
}
else {
printf("ok %d - uc_emu_start complete\n", log_num++);
}
printf("# END execution\n");
//make sure that data got copied
// fill in sections that shouldn't get touched
if (uc_mem_read(handle, 0x201000, (uint8_t*)readbuf, 20)) {
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
}
else {
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
if (memcmp(buf1, readbuf, 20)) {
printf("not ok %d - write buffer contents are incorrect\n", log_num++);
}
else {
printf("ok %d - write buffer contents are correct\n", log_num++);
}
}
if (uc_close(&handle) == UC_ERR_OK) {
printf("ok %d - uc_close complete\n", log_num++);
}
else {
printf("not ok %d - uc_close complete\n", log_num++);
}
return 0;
}