Exemple #1
0
void
load_overlay(int fd, int start_segment, int reloc_segment)
{
    struct exehdr hdr;
    int text_size;
    int exe_file;

    /* read exe header */
    if (read (fd, &hdr, sizeof hdr) != sizeof hdr)
	fatal ("can't read header\n");
    
    /* proper header ? */
    if (hdr.magic == 0x5a4d) {
	exe_file = 1;
	text_size = (hdr.size - 1) * 512 + hdr.bytes_on_last_page
	    - hdr.hdr_size * 16;
    } else {
	exe_file = 0;
    }

    if (!exe_file)
	load_com(fd, start_segment);
    else
	load_exe(fd, start_segment, reloc_segment, &hdr, text_size);
}
Exemple #2
0
int main(int argc, char **argv)
{
    uc_engine *uc;
    uc_hook trace;
    uc_err err;

    uint8_t memory[MEM_SIZE];

    if (argc == 1) {
        usage(argv[0]);
        return -1;
    }

    const char *fname = argv[1];

    err = uc_open (UC_ARCH_X86, UC_MODE_16, &uc);
    if (err) {
        fprintf(stderr, "Cannot initialize unicorn\n");
        return 1;
    }

    // map 64KB in
    if (uc_mem_map (uc, 0, MEM_SIZE, UC_PROT_ALL)) {
        fprintf(stderr, "Failed to write emulation code to memory, quit!\n");
        uc_close(uc);
        return 0;
    }

    // initialize internal settings
    int21_init();

    //load executable
    size_t fsize = load_com(uc, memory, fname);

    // setup PSP
    setup_psp(0, memory, argc, argv);

    // write machine code to be emulated in, including the prefix PSP
    uc_mem_write(uc, 0, memory, DOS_ADDR + fsize);

    // handle interrupt ourself
    uc_hook_add(uc, &trace, UC_HOOK_INTR, hook_intr, NULL);

    err = uc_emu_start(uc, DOS_ADDR, DOS_ADDR + 0x10000, 0, 0);
    if (err) {
        fprintf(stderr, "Failed on uc_emu_start() with error returned %u: %s\n",
                err, uc_strerror(err));
    }

    uc_close(uc);

    return 0;
}
Exemple #3
0
void
load_command(regcontext_t *REGS, int run, int fd, char *cmd_name, 
	     u_short *param, char **argv, char **envs)
{
    struct exehdr hdr;
    int min_memory, max_memory;
    int biggest;
    int envseg;
    char *psp;
    int text_size = 0;
    int i;
    int start_segment;
    int exe_file;
    char *p;
    int used, n;
    char *fcb;
    int newpsp;
    u_short init_cs, init_ip, init_ss, init_sp, init_ds, init_es;

    if (envs)
	envseg = make_environment(cmd_name, envs);
    else
	envseg = env_s[curpsp];

    /* read exe header */
    if (read (fd, &hdr, sizeof hdr) != sizeof hdr)
	fatal ("can't read header\n");
    
    /* proper header ? */
    if (hdr.magic == 0x5a4d) {
	exe_file = 1;
	text_size = (hdr.size - 1) * 512 + hdr.bytes_on_last_page
	    - hdr.hdr_size * 16;
	min_memory = hdr.min_memory + (text_size + 15)/16;
	max_memory = hdr.max_memory + (text_size + 15)/16;
    } else {
	exe_file = 0;
	min_memory = 64 * (1024/16);
	max_memory = 0xffff;
    }
    
    /* alloc mem block */
    pspseg = mem_alloc(max_memory, 1, &biggest);
    if (pspseg == 0) {
	if (biggest < min_memory ||
	    (pspseg = mem_alloc(biggest, 1, NULL)) == 0)
	    fatal("not enough memory: needed %d have %d\n",
		  min_memory, biggest);
	
	max_memory = biggest;
    }
    
    mem_change_owner(pspseg, pspseg);
    mem_change_owner(envseg, pspseg);
    
    /* create psp */
    newpsp = curpsp + 1;
    psp_s[newpsp] = pspseg;
    env_s[newpsp] = envseg;
    
    psp = (char *)MAKEPTR(pspseg, 0);
    memset(psp, 0, 256);
    
    psp[0] = 0xcd;
    psp[1] = 0x20;

    *(u_short *)&psp[2] = pspseg + max_memory;
    
    /*
     * this is supposed to be a long call to dos ... try to fake it
     */
    psp[5] = 0xcd;
    psp[6] = 0x99;
    psp[7] = 0xc3;
    
    *(u_short *)&psp[0x16] = psp_s[curpsp];
    psp[0x18] = 1;
    psp[0x19] = 1;
    psp[0x1a] = 1;
    psp[0x1b] = 0;
    psp[0x1c] = 2;
    memset(psp + 0x1d, 0xff, 15);
    
    *(u_short *)&psp[0x2c] = envseg;
    
    *(u_short *)&psp[0x32] = 20;
    *(u_long *)&psp[0x34] = MAKEVEC(pspseg, 0x18);
    *(u_long *)&psp[0x38] = 0xffffffff;
    
    psp[0x50] = 0xcd;
    psp[0x51] = 0x98;
    psp[0x52] = 0xc3;
    
    p = psp + 0x81;
    *p = 0;
    used = 0;
    for (i = 0; argv[i]; i++) {
	n = strlen(argv[i]);
	if (used + 1 + n > 0x7d)
	    break;
	*p++ = ' ';
	memcpy(p, argv[i], n);
	p += n;
	used += n;
    }

    psp[0x80] = strlen(psp + 0x81);
    psp[0x81 + psp[0x80]] = 0x0d;
    psp[0x82 + psp[0x80]] = 0;
    
    p = psp + 0x81;
    parse_filename(0x00, p, psp + 0x5c, &n);
    p += n;
    parse_filename(0x00, p, psp + 0x6c, &n);
    
    if (param[4]) {
	fcb = (char *)MAKEPTR(param[4], param[3]);
	memcpy(psp + 0x5c, fcb, 16);
    }
    if (param[6]) {
	fcb = (char *)MAKEPTR(param[6], param[5]);
	memcpy(psp + 0x6c, fcb, 16);
    }

#if 0
    printf("005c:");
    for (n = 0; n < 16; n++)
	printf(" %02x", psp[0x5c + n]);
    printf("\n");
    printf("006c:");
    for (n = 0; n < 16; n++)
	printf(" %02x", psp[0x6c + n]);
    printf("\n");
#endif

    disk_transfer_addr = MAKEVEC(pspseg, 0x80);
    
    start_segment = pspseg + 0x10;
    
    if (!exe_file) {
	load_com(fd, start_segment);

	init_cs = pspseg;
	init_ip = 0x100;
	init_ss = init_cs;
	init_sp = 0xfffe;
	init_ds = init_cs;
	init_es = init_cs;
    } else {
	load_exe(fd, start_segment, start_segment, &hdr, text_size);
	
	init_cs = hdr.init_cs + start_segment;
	init_ip = hdr.init_ip;
	init_ss = hdr.init_ss + start_segment;
	init_sp = hdr.init_sp;
	init_ds = pspseg;
	init_es = init_ds;
    }

    debug(D_EXEC, "cs:ip = %04x:%04x, ss:sp = %04x:%04x, "
	  "ds = %04x, es = %04x\n",
	  init_cs, init_ip, init_ss, init_sp, init_ds, init_es);
    
    if (run) {
	frames[newpsp] = *REGS;
	curpsp = newpsp;
	
	R_EFLAGS = 0x20202;
	R_CS = init_cs;
	R_IP = init_ip;
	R_SS = init_ss;
	R_SP = init_sp;
	R_DS = init_ds;
	R_ES = init_es;

	R_AX = R_BX = R_CX = R_DX = R_SI = R_DI = R_BP = 0;

    } else {
	param[7] = init_sp;
	param[8] = init_ss;
	param[9] = init_ip;
	param[10] = init_cs;
    }
}