diff options
| author | Louis Burda <quent.burda@gmail.com> | 2023-01-24 16:17:45 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2023-01-24 16:17:45 +0100 |
| commit | 65daf1cb353f4ba5e2f08ccbce6b0d5220b0099a (patch) | |
| tree | 87ab9ad37716cf5c0c110e905e95113de460d607 | |
| parent | e4762c2cdefacf13d26967b7e5f0735c2748026b (diff) | |
| download | cachepc-65daf1cb353f4ba5e2f08ccbce6b0d5220b0099a.tar.gz cachepc-65daf1cb353f4ba5e2f08ccbce6b0d5220b0099a.zip | |
Create flat binaries to support more complex guests
| -rwxr-xr-x | Makefile | 31 | ||||
| -rw-r--r-- | README | 2 | ||||
| -rw-r--r-- | cachepc/kvm.c | 1 | ||||
| m--------- | linux | 0 | ||||
| -rwxr-xr-x | test/.gitignore | 8 | ||||
| -rw-r--r-- | test/guest.lds | 13 | ||||
| -rw-r--r-- | test/kvm-eviction-with_guest.S | 14 | ||||
| -rw-r--r-- | test/kvm-eviction-without_guest.S | 12 | ||||
| -rw-r--r-- | test/kvm-eviction.c | 15 | ||||
| -rw-r--r-- | test/kvm-eviction_guest.S | 26 | ||||
| -rw-r--r-- | test/kvm-pagestep.c | 8 | ||||
| -rw-r--r-- | test/kvm-pagestep_guest.S | 21 | ||||
| -rw-r--r-- | test/kvm-step.c | 8 | ||||
| -rw-r--r-- | test/kvm-step_guest.S | 28 | ||||
| -rw-r--r-- | test/kvm.c | 78 | ||||
| -rw-r--r-- | test/kvm.h | 25 | ||||
| -rw-r--r-- | test/qemu-aes.c (renamed from test/qemu-aes_host.c) | 0 | ||||
| -rw-r--r-- | test/qemu-eviction.c (renamed from test/qemu-eviction_host.c) | 7 | ||||
| -rw-r--r-- | test/util.c | 1 | ||||
| -rwxr-xr-x | util/disasm | 4 |
20 files changed, 178 insertions, 124 deletions
@@ -6,9 +6,11 @@ JOBS ?= $(CORES) PWD := $(shell pwd) BINS = test/eviction test/kvm-eviction -BINS += test/kvm-step test/kvm-pagestep -# BINS += test/qemu-eviction_guest test/qemu-eviction_host -# BINS += test/qemu-aes_guest test/qemu-aes_host +BINS += test/kvm-eviction-with_guest test/kvm-eviction-without_guest +BINS += test/kvm-step test/kvm-step_guest +BINS += test/kvm-pagestep test/kvm-pagestep_guest +#BINS += test/qemu-eviction_guest test/qemu-eviction +# BINS += test/qemu-aes_guest test/qemu-aes BINS += util/debug util/reset CFLAGS = -I . -I linux/usr/include @@ -17,7 +19,8 @@ CFLAGS += -fsanitize=address LDLIBS = -lpthread -CACHEPC_UAPI = cachepc/uapi.h cachepc/const.h +TEST_SRCS = test/util.c test/util.h test/kvm.c test/kvm.h +TEST_SRCS += cachepc/uapi.h cachepc/const.h all: build $(BINS) @@ -57,19 +60,25 @@ prep: util/%: util/%.c $(CACHEPC_UAPI) -test/eviction: test/eviction.c test/util.c $(CACHEPC_UAPI) +test/%.o: test/%.c + $(CC) -c -o $@ $^ $(CFLAGS) + +test/%.o: test/%.S + $(CC) -c -o $@ $^ $(CFLAGS) + +test/%_guest: test/%_guest.o test/guest.lds + $(LD) -Ttest/guest.lds -o $@ $< + +test/eviction: test/eviction.c test/util.c $(TEST_SRCS) $(CC) -o $@ $(filter %.c,$^) $(filter %.S,$^) $(CFLAGS) $(LDLIBS) -test/kvm-eviction: test/kvm-eviction.c test/kvm-eviction_guest.S test/util.c \ - test/util.h test/kvm.c test/kvm.h test/kvm-eviction.h $(CACHEPC_UAPI) +test/kvm-eviction: test/kvm-eviction.c test/kvm-eviction.h $(TEST_SRCS) $(CC) -o $@ $(filter %.c,$^) $(filter %.S,$^) $(CFLAGS) $(LDLIBS) -test/kvm-step: test/kvm-step.c test/kvm-step_guest.S \ - test/util.c test/util.h test/kvm.c test/kvm.h $(CACHEPC_UAPI) +test/kvm-step: test/kvm-step.c $(TEST_SRCS) $(CC) -o $@ $(filter %.c,$^) $(filter %.S,$^) $(CFLAGS) $(LDLIBS) -test/kvm-pagestep: test/kvm-pagestep.c test/kvm-pagestep_guest.S \ - test/util.c test/util.h test/kvm.c test/kvm.h $(CACHEPC_UAPI) +test/kvm-pagestep: test/kvm-pagestep.c $(TEST_SRCS) $(CC) -o $@ $(filter %.c,$^) $(filter %.S,$^) $(CFLAGS) $(LDLIBS) .PHONY: all clean host build load prep @@ -1,7 +1,7 @@ CachePC ======= -This repository contains proof-of-concept code for a novel cache side-channel +This repository contains proof-of-concept code for a cache side-channel attack dubbed PRIME+COUNT that we demonstrate can be used to circumvent AMD's latest secure virtualization solution SEV-SNP to access sensitive guest information. diff --git a/cachepc/kvm.c b/cachepc/kvm.c index 3809737..559388f 100644 --- a/cachepc/kvm.c +++ b/cachepc/kvm.c @@ -513,7 +513,6 @@ cachepc_kvm_track_mode_ioctl(void __user *arg_user) cachepc_untrack_all(vcpu, KVM_PAGE_TRACK_ACCESS); cachepc_untrack_all(vcpu, KVM_PAGE_TRACK_WRITE); - cachepc_apic_timer = 0; cachepc_apic_oneshot = false; cachepc_singlestep = false; cachepc_singlestep_reset = false; diff --git a/linux b/linux -Subproject abccf24ec694dd3d9196b8c03b9c1f0b3f2575a +Subproject fa821762ad7ed234d85318f150bb11ce9a3e2c7 diff --git a/test/.gitignore b/test/.gitignore index 2549182..ad9a84a 100755 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,7 +1,15 @@ +*.o eviction kvm-eviction +kvm-eviction-with_guest +kvm-eviction-without_guest kvm-step +kvm-step_guest kvm-pagestep +kvm-pagestep_guest qemu-eviction +qemu-eviction_guest qemu-aes +qemu-aes_guest qemu-poc +qemu-poc_guest diff --git a/test/guest.lds b/test/guest.lds new file mode 100644 index 0000000..bced66e --- /dev/null +++ b/test/guest.lds @@ -0,0 +1,13 @@ +OUTPUT_FORMAT(binary) + +SECTIONS +{ + .text : { + . = 0; + *(.text) + } + + .data : { + *(.data) + } +} diff --git a/test/kvm-eviction-with_guest.S b/test/kvm-eviction-with_guest.S new file mode 100644 index 0000000..08b365c --- /dev/null +++ b/test/kvm-eviction-with_guest.S @@ -0,0 +1,14 @@ +#include "test/kvm-eviction.h" +#include "cachepc/const.h" + +.text +.align(16) +.code16gcc + +guest: + mov $(L1_LINESIZE * (L1_SETS + TARGET_SET)), %bx + movb (%bx), %bl + hlt + + jmp guest + diff --git a/test/kvm-eviction-without_guest.S b/test/kvm-eviction-without_guest.S new file mode 100644 index 0000000..896a933 --- /dev/null +++ b/test/kvm-eviction-without_guest.S @@ -0,0 +1,12 @@ +#include "test/kvm-eviction.h" +#include "cachepc/const.h" + +.text +.align(16) +.code16gcc + +guest: + hlt + + jmp guest + diff --git a/test/kvm-eviction.c b/test/kvm-eviction.c index 5347f35..cc1fbe3 100644 --- a/test/kvm-eviction.c +++ b/test/kvm-eviction.c @@ -18,11 +18,6 @@ #define TARGET_CORE 2 #define SECONDARY_CORE 3 -extern uint8_t guest_with_start[]; -extern uint8_t guest_with_stop[]; -extern uint8_t guest_without_start[]; -extern uint8_t guest_without_stop[]; - void collect(struct kvm *kvm, uint8_t *counts) { @@ -47,6 +42,7 @@ int main(int argc, const char **argv) { struct kvm vms[2]; + struct guest guests[2]; uint8_t counts[2][SAMPLE_COUNT][L1_SETS]; uint8_t baseline[L1_SETS]; int i, k, ret; @@ -64,8 +60,13 @@ main(int argc, const char **argv) kvm_setup_init(); - vm_init(&vms[WITH], guest_with_start, guest_with_stop); - vm_init(&vms[WITHOUT], guest_without_start, guest_without_stop); + guest_init(&guests[WITH], "test/kvm-eviction-with_guest"); + vm_init(&vms[WITH], &guests[WITH]); + guest_deinit(&guests[WITH]); + + guest_init(&guests[WITHOUT], "test/kvm-eviction-without_guest"); + vm_init(&vms[WITHOUT], &guests[WITHOUT]); + guest_deinit(&guests[WITHOUT]); /* reset kernel module state */ ret = ioctl(kvm_dev, KVM_CPC_RESET); diff --git a/test/kvm-eviction_guest.S b/test/kvm-eviction_guest.S deleted file mode 100644 index 16a07a5..0000000 --- a/test/kvm-eviction_guest.S +++ /dev/null @@ -1,26 +0,0 @@ -#include "test/kvm-eviction.h" -#include "cachepc/const.h" - -.global guest_with_start -.global guest_with_stop - -.global guest_without_start -.global guest_without_stop - -.align(16) -.code16gcc - -guest_with_start: - mov $(L1_LINESIZE * (L1_SETS + TARGET_SET)), %bx - movb (%bx), %bl - hlt - - mov $0x00, %ax - jmp *%ax -guest_with_stop: - -guest_without_start: - hlt - mov $0x00, %ax - jmp *%ax -guest_without_stop: diff --git a/test/kvm-pagestep.c b/test/kvm-pagestep.c index e04429b..5f9d025 100644 --- a/test/kvm-pagestep.c +++ b/test/kvm-pagestep.c @@ -18,9 +18,6 @@ #define TARGET_CORE 2 #define SECONDARY_CORE 3 -extern uint8_t guest_start[]; -extern uint8_t guest_stop[]; - static int child; uint64_t @@ -58,6 +55,7 @@ int main(int argc, const char **argv) { struct ipc *ipc; + struct guest guest; struct kvm kvm; uint64_t eventcnt; uint32_t arg; @@ -82,7 +80,9 @@ main(int argc, const char **argv) if (child == 0) { pin_process(0, TARGET_CORE, true); - vm_init(&kvm, guest_start, guest_stop); + guest_init(&guest, "test/kvm-pagestep_guest"); + vm_init(&kvm, &guest); + guest_deinit(&guest); /* reset kernel module state */ ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL); diff --git a/test/kvm-pagestep_guest.S b/test/kvm-pagestep_guest.S index a936d2d..b40d230 100644 --- a/test/kvm-pagestep_guest.S +++ b/test/kvm-pagestep_guest.S @@ -2,28 +2,23 @@ #define TARGET_SET 15 -.global guest_start -.global guest_stop - +.text .align(16) .code16gcc -guest_start: +guest: .rept L1_SIZE - nop + nop .endr - mov $0x01, %bx - cmp $0x00, %bx + mov $0x01, %bx + cmp $0x00, %bx - # NOTE: this needs to be a relative jmp - je skip + je skip .rept L1_LINESIZE * L1_SETS * 2 - nop + nop .endr skip: - mov $0x00, %ax - jmp *%ax -guest_stop: + jmp guest diff --git a/test/kvm-step.c b/test/kvm-step.c index e3df5d2..ce715d2 100644 --- a/test/kvm-step.c +++ b/test/kvm-step.c @@ -18,9 +18,6 @@ #define TARGET_CORE 2 #define SECONDARY_CORE 3 -extern uint8_t guest_start[]; -extern uint8_t guest_stop[]; - static int child; uint64_t @@ -64,6 +61,7 @@ int main(int argc, const char **argv) { struct ipc *ipc; + struct guest guest; struct kvm kvm; uint8_t baseline[L1_SETS]; struct cpc_event event; @@ -90,7 +88,9 @@ main(int argc, const char **argv) if (child == 0) { pin_process(0, TARGET_CORE, true); - vm_init(&kvm, guest_start, guest_stop); + guest_init(&guest, "test/kvm-step_guest"); + vm_init(&kvm, &guest); + guest_deinit(&guest); /* reset kernel module state */ ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL); diff --git a/test/kvm-step_guest.S b/test/kvm-step_guest.S index 3d1b0e7..dcc8ff3 100644 --- a/test/kvm-step_guest.S +++ b/test/kvm-step_guest.S @@ -2,26 +2,22 @@ #define TARGET_SET 15 -.global guest_start -.global guest_stop - +.text .align(16) .code16gcc -guest_start: - mov $(L1_LINESIZE * (L1_SETS + 11)), %bx - movb (%bx), %bl - hlt +guest: + mov $(L1_LINESIZE * (L1_SETS + 11)), %bx + movb (%bx), %bl + hlt - mov $(L1_LINESIZE * (L1_SETS + 13)), %bx - movb (%bx), %bl - hlt + mov $(L1_LINESIZE * (L1_SETS + 13)), %bx + movb (%bx), %bl + hlt - mov $(L1_LINESIZE * (L1_SETS + 15)), %bx - movb (%bx), %bl - hlt + mov $(L1_LINESIZE * (L1_SETS + 15)), %bx + movb (%bx), %bl + hlt - mov $0x00, %ax - jmp *%ax -guest_stop: + jmp guest @@ -204,6 +204,35 @@ snp_dbg_decrypt_rip(int vmfd) } void +guest_init(struct guest *guest, const char *filename) +{ + FILE *f; + + f = fopen(filename, "r"); + if (!f) err(1, "fopen"); + + fseek(f, 0, SEEK_END); + guest->code_size = ftell(f); + fseek(f, 0, SEEK_SET); + + guest->code = malloc(guest->code_size); + if (!guest->code) err(1, "malloc"); + + if (!fread(guest->code, guest->code_size, 1, f)) + errx(1, "read guest"); + + guest->mem_size = 0; + + fclose(f); +} + +void +guest_deinit(struct guest *guest) +{ + free(guest->code); +} + +void kvm_create_vm(struct kvm *kvm) { kvm->vmfd = ioctl(kvm_dev, KVM_CREATE_VM, 0); @@ -211,20 +240,19 @@ kvm_create_vm(struct kvm *kvm) } void -kvm_init_memory(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop) +kvm_init_memory(struct kvm *kvm, size_t mem_size, void *code, size_t code_size) { struct kvm_userspace_memory_region region; int ret; - kvm->memsize = ramsize; + kvm->memsize = mem_size; kvm->mem = mmap(NULL, kvm->memsize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (!kvm->mem) err(1, "mmap kvm->mem"); /* nop slide oob to detect errors quickly */ memset(kvm->mem, 0x90, kvm->memsize); - assert(code_stop - code_start <= kvm->memsize); - memcpy(kvm->mem, code_start, code_stop - code_start); + assert(code_size <= kvm->memsize); + memcpy(kvm->mem, code, code_size); memset(®ion, 0, sizeof(region)); region.slot = 0; @@ -279,12 +307,11 @@ kvm_init_regs(struct kvm *kvm) } void -kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop) +kvm_init(struct kvm *kvm, struct guest *guest) { kvm_create_vm(kvm); - kvm_init_memory(kvm, ramsize, code_start, code_stop); + kvm_init_memory(kvm, guest->mem_size, guest->code, guest->code_size); kvm_create_vcpu(kvm); @@ -292,8 +319,7 @@ kvm_init(struct kvm *kvm, size_t ramsize, } void -sev_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop) +sev_kvm_init(struct kvm *kvm, struct guest *guest) { struct kvm_sev_launch_update_data update; struct kvm_sev_launch_start start; @@ -301,7 +327,7 @@ sev_kvm_init(struct kvm *kvm, size_t ramsize, kvm_create_vm(kvm); - kvm_init_memory(kvm, ramsize, code_start, code_stop); + kvm_init_memory(kvm, guest->mem_size, guest->code, guest->code_size); /* Enable SEV for vm */ ret = sev_ioctl(kvm->vmfd, KVM_SEV_INIT, NULL, &fwerr); @@ -323,7 +349,7 @@ sev_kvm_init(struct kvm *kvm, size_t ramsize, /* Prepare the vm memory (by encrypting it) */ memset(&update, 0, sizeof(update)); update.uaddr = (uintptr_t) kvm->mem; - update.len = ramsize; + update.len = kvm->memsize; ret = sev_ioctl(kvm->vmfd, KVM_SEV_LAUNCH_UPDATE_DATA, &update, &fwerr); if (ret == -1) errx(1, "KVM_SEV_LAUNCH_UPDATE_DATA: (%s) %s", strerror(errno), sev_fwerr_str(fwerr)); @@ -342,8 +368,7 @@ sev_kvm_init(struct kvm *kvm, size_t ramsize, } void -sev_es_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop) +sev_es_kvm_init(struct kvm *kvm, struct guest *guest) { struct kvm_sev_launch_update_data update; struct kvm_sev_launch_start start; @@ -351,7 +376,7 @@ sev_es_kvm_init(struct kvm *kvm, size_t ramsize, kvm_create_vm(kvm); - kvm_init_memory(kvm, ramsize, code_start, code_stop); + kvm_init_memory(kvm, guest->mem_size, guest->code, guest->code_size); /* Enable SEV for vm */ ret = sev_ioctl(kvm->vmfd, KVM_SEV_ES_INIT, NULL, &fwerr); @@ -373,7 +398,7 @@ sev_es_kvm_init(struct kvm *kvm, size_t ramsize, /* Prepare the vm memory (by encrypting it) */ memset(&update, 0, sizeof(update)); update.uaddr = (uintptr_t) kvm->mem; - update.len = ramsize; + update.len = kvm->memsize; ret = sev_ioctl(kvm->vmfd, KVM_SEV_LAUNCH_UPDATE_DATA, &update, &fwerr); if (ret == -1) errx(1, "KVM_SEV_LAUNCH_UPDATE_DATA: (%s) %s", strerror(errno), sev_fwerr_str(fwerr)); @@ -397,8 +422,7 @@ sev_es_kvm_init(struct kvm *kvm, size_t ramsize, } void -sev_snp_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop) +sev_snp_kvm_init(struct kvm *kvm, struct guest *guest) { struct kvm_sev_snp_launch_update update; struct kvm_sev_snp_launch_start start; @@ -409,7 +433,7 @@ sev_snp_kvm_init(struct kvm *kvm, size_t ramsize, kvm_create_vm(kvm); - kvm_init_memory(kvm, ramsize, code_start, code_stop); + kvm_init_memory(kvm, guest->mem_size, guest->code, guest->code_size); /* Enable SEV for vm */ memset(&init, 0, sizeof(init)); @@ -440,7 +464,7 @@ sev_snp_kvm_init(struct kvm *kvm, size_t ramsize, /* Prepare the vm memory */ memset(&update, 0, sizeof(update)); update.uaddr = (uintptr_t) kvm->mem; - update.len = ramsize; + update.len = kvm->memsize; update.start_gfn = 0; update.page_type = KVM_SEV_SNP_PAGE_TYPE_NORMAL; ret = sev_ioctl(kvm->vmfd, KVM_SEV_SNP_LAUNCH_UPDATE, &update, &fwerr); @@ -495,19 +519,19 @@ vm_get_rip(struct kvm *kvm) } void -vm_init(struct kvm *kvm, void *code_start, void *code_end) +vm_init(struct kvm *kvm, struct guest *guest) { - size_t ramsize; + if (!guest->mem_size) + guest->mem_size = L1_SIZE * 2; - ramsize = L1_SIZE * 2; if (!strcmp(vmtype, "kvm")) { - kvm_init(kvm, ramsize, code_start, code_end); + kvm_init(kvm, guest); } else if (!strcmp(vmtype, "sev")) { - sev_kvm_init(kvm, ramsize, code_start, code_end); + sev_kvm_init(kvm, guest); } else if (!strcmp(vmtype, "sev-es")) { - sev_es_kvm_init(kvm, ramsize, code_start, code_end); + sev_es_kvm_init(kvm, guest); } else if (!strcmp(vmtype, "sev-snp")) { - sev_snp_kvm_init(kvm, ramsize, code_start, code_end); + sev_snp_kvm_init(kvm, guest); } else { errx(1, "invalid version"); } @@ -1,5 +1,7 @@ #pragma once +#include "util.h" + #include <stdint.h> #include <stdlib.h> @@ -22,6 +24,12 @@ struct kvm { struct kvm_run *run; }; +struct guest { + void *code; + size_t code_size; + size_t mem_size; +}; + const char *sev_fwerr_str(int code); const char *sev_gstate_str(int code); @@ -33,19 +41,18 @@ uint64_t sev_dbg_decrypt_rip(int vmfd); void snp_dbg_decrypt(int vmfd, void *src, void *dst, size_t size); uint64_t snp_dbg_decrypt_rip(int vmfd); -void kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop); -void sev_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop); -void sev_es_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop); -void sev_snp_kvm_init(struct kvm *kvm, size_t ramsize, - void *code_start, void *code_stop); +void guest_init(struct guest *guest, const char *filename); +void guest_deinit(struct guest *guest); + +void kvm_init(struct kvm *kvm, struct guest *guest); +void sev_kvm_init(struct kvm *kvm, struct guest *guest); +void sev_es_kvm_init(struct kvm *kvm, struct guest *guest); +void sev_snp_kvm_init(struct kvm *kvm, struct guest *guest); void kvm_deinit(struct kvm *kvm); void parse_vmtype(int argc, const char **argv); uint64_t vm_get_rip(struct kvm *kvm); -void vm_init(struct kvm *kvm, void *code_start, void *code_end); +void vm_init(struct kvm *kvm, struct guest *guest); void vm_deinit(struct kvm *kvm); void kvm_setup_init(void); diff --git a/test/qemu-aes_host.c b/test/qemu-aes.c index 0e6dff6..0e6dff6 100644 --- a/test/qemu-aes_host.c +++ b/test/qemu-aes.c diff --git a/test/qemu-eviction_host.c b/test/qemu-eviction.c index 87a5edd..2761d8c 100644 --- a/test/qemu-eviction_host.c +++ b/test/qemu-eviction.c @@ -260,9 +260,8 @@ main(int argc, const char **argv) struct cpc_event event; cpc_msrmt_t baseline[64]; int ret, i; - - kvm_dev = open("/dev/kvm", O_RDWR); - if (!kvm_dev) err(1, "open /dev/kvm"); + + kvm_setup_init(); setvbuf(stdout, NULL, _IONBF, 0); @@ -357,5 +356,7 @@ main(int argc, const char **argv) arg = KVM_PAGE_TRACK_EXEC; ret = ioctl(kvm_dev, KVM_CPC_UNTRACK_ALL, &arg); if (ret) err(1, "ioctl UNTRACK_ALL"); + + kvm_setup_deinit(); } diff --git a/test/util.c b/test/util.c index 6fc38d2..8b27578 100644 --- a/test/util.c +++ b/test/util.c @@ -192,3 +192,4 @@ ipc_wait_parent(struct ipc *ipc) ipc->has_sig_parent = false; pthread_mutex_unlock(&ipc->lock); } + diff --git a/util/disasm b/util/disasm index d8247e1..99b2d21 100755 --- a/util/disasm +++ b/util/disasm @@ -1,12 +1,12 @@ #!/bin/sh if [ $# -lt 2 ]; then - echo "Usage: guest_asm FILE FUNC (guest)" + echo "Usage: guest_asm FILE FUNC" exit 1 fi ARCH="i386" -if [ "$3" = "guest" ]; then +if [ "$2" = "guest" ]; then ARCH="i8086" fi |
