⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadprg.c

📁 大量的汇编程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 * FILE: loadprg.c							     *
 *									     *
 * DESC:								     *
 *	- loader for coff/a.out programs				     *
 *	- set args,environment						     *
 *	- load text,data (if not DPMI 1.0)				     *
 *									     *
 * Copyright (C) 1993,1994						     *
 *	Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld		     *
 *	email: rainer@mathematik.uni-bielefeld.de			     *
 *									     *
 *****************************************************************************/

#include <string.h>
#include "DPMI.H"
#include "DPMI10.H"
#include "PRINTF.H"
#include "RMLIB.H"
#include "PROCESS.H"
#include "FS.H"
#include "GNUAOUT.H"
#include "LOADPRG.H"
#include "COPY32.H"
#include "START32.H"
#include "CDOSX32.H"
#include "RSX.H"
#include "DOSERRNO.H"

static int skip_exe_hdr(int filehandle, DWORD * headoff, NEWPROCESS *p)
{
    struct exe_hdr exehdr;
    struct emx_hdr2 emxhdr;

    rm_read(filehandle, &exehdr, sizeof(struct exe_hdr));

    if (exehdr.signatur == 0x5a4d) {	/* falls exe-kopf */
	*headoff = ((DWORD) exehdr.hdr_para) * 16;
	rm_lseek(filehandle, *headoff, SEEK_SET);
	rm_read(filehandle, &emxhdr, sizeof(emxhdr));

	if (memcmp(emxhdr.sig, "emx", 3) == 0) {
	    *headoff = *(DWORD *) emxhdr.next_hdr;
	    if (emxhdr.option[0]) {
		char *s = emxhdr.option;
		for (; *s != '\0'; ++s) {
		    while (*s == ' ')
			++s;
		    if (*s == '-') {
			s = scan_for_option(++s, p);
		    } else
			break;
		}
	    }
	}

	else if (memcmp(emxhdr.sig, "rsx", 3) == 0)
	    goto fail;	    /* prevent loading rsx32.exe as a.out */

	else {	    /* not a emx file */
	    long new_off;

	    rm_lseek(filehandle, 0x3C, SEEK_SET);
	    rm_read(filehandle, &new_off, sizeof(long));
	    if (new_off) {
		char pe_sig[4];
		rm_lseek(filehandle, new_off, SEEK_SET);
		rm_read(filehandle, pe_sig, sizeof(pe_sig));
		if (pe_sig[0])
		    *headoff = new_off + 4;
	    }
	    else { /* djgpp */
		*headoff = (DWORD) exehdr.high * 512L;
		if (exehdr.low)
		    *headoff += (DWORD) exehdr.low - 512L;
	    }
	}
    }	/* exe files */

    if (rm_lseek(filehandle, *headoff, SEEK_SET) == -1L)
	goto fail;
    return 0;

  fail:
    *headoff = 0;
    rm_lseek(filehandle, 0, SEEK_SET);
    return -1;
}

/*
** arguments and environment at process start
**
**	environment and argument strings
**	argv[]
**	envp[]
**	pointer to env[0]
**	pointer to argv[0]
**	int argc
**	<- ESP
*/
int argvenv(int argc, char **argv, int envc, char **env, NEWPROCESS * proc)
{
    int i;
    DWORD len, stkp;
    DWORD *vectors;
    UINT count = 3;		/* 0=argc 1=argv 2=env */

    vectors = (DWORD *) iobuf;

    stkp = proc->stackp32;

    /* store env strings in user stack, built vectors */
    for (i = 0; i < envc; i++) {
	len = (DWORD) (UINT) strlen(env[i]) + 1;
	stkp -= len;
	stkp &= ~3L;		/* align4 */
	cpy16_32(proc->data32sel, stkp, env[i], len);
	vectors[count++] = stkp;
    }
    vectors[count++] = 0;	/* last is a NULL pointer */

    /* store arg strings in user stack, built vectors */

    for (i = 0; i < argc; i++) {
	len = (DWORD) (UINT) strlen(argv[i]) + 1;
	stkp -= len;
	stkp &= ~3L;
	cpy16_32(proc->data32sel, stkp, argv[i], len);
	vectors[count] = stkp;
	count++;
	/* for emx: add flag */
	stkp -= 1;
	put_user_byte(proc->data32sel, stkp, 0x80);
    }
    vectors[count++] = 0;	/* last is a NULL pointer */

    stkp &= ~3L;
    len = (DWORD) (count * sizeof(long));
    stkp -= len;
    vectors[0] = argc;
    vectors[1] = stkp + (4L + envc) * sizeof(long);	/* & vectors[3+nenvp+1] */
    vectors[2] = stkp + 3 * sizeof(long);	/* & vectors[3] */
    cpy16_32(proc->data32sel, stkp, vectors, len);

    if (proc->p_flags & PF_EMX_FILE)
	stkp += 3 * 4;

    proc->stackp32 = stkp;
    return 0;
}

void cpy_exename_to_stack(NEWPROCESS *proc, char *name)
{
    int len = strlen(name) + 1;
    long name_pos = proc->stackp32 - (long) (len + 2 * sizeof(DWORD));

    proc->stackp32 -= sizeof(DWORD);
    store32(proc->data32sel, proc->stackp32, name_pos);
    proc->stackp32 -= sizeof(DWORD);
    store32(proc->data32sel, proc->stackp32, (long) len);
    proc->stackp32 -= (long) len;
    cpy16_32(proc->data32sel, proc->stackp32, name, (long) len);
}

int readin_file(short handle, short r_ds, long r_edx, long count)
{
    long bytes;
    int rc;

    while (count > 0) {
	bytes = (count <= IOBUF_SIZE) ? count : (DWORD) IOBUF_SIZE;

	rc = rm_read(handle, iobuf, (short) bytes);
	cpy16_32(r_ds, r_edx, iobuf, rc);
	if (bytes != rc)
	    break;
	count -= bytes;
	r_edx += bytes;
    }
    return 0;
}

/*
**
** RSX program layout:
**
**
**  DPMI 0.9 :	 fixed stack
**		 never ending heap
**
**  emx style
**  |--------------------------------------------------------------
**  |stack|    code    |  data/bss  |  stack,if>64KB |	heap -> ...
**  |--------------------------------------------------------------
**  0	  ^64 KB       ^(n x 64KB)
**
**
**  old djgpp style
**  |--------------------------------------------------------------
**  |	|    code	 | stack    |  data/bss  | heap -> ...
**  |--------------------------------------------------------------
**  0	^4K			    ^0x400000
**
**  djgpp style 1.11
**  |--------------------------------------------------------------
**  |  code	|  data/bss  | stack  | heap -> ...
**  |--------------------------------------------------------------
**  0		^ 4 Kb align ^
**
**
**
**  DPMI 1.0 :	 address room = 64 MegaBytes
**
**  |--------------------------------------------...-----------------------|
**  |	  |  code   |  |  data/bss  |  heap ->	      <- stack	| mappings |
**  |	  |	    |  |	    |				| DOS 1MB  |
**  |--------------------------------------------...-----------------------|
**  0								^60	   64
**
*/

#define SHORT_EMX_STACK (0x10000L-0x1000L)	/* 64 KB - one R/O page */
#define DEFAULT_STACK (0x40000L)		/* 256 KB */
#define TEXT 0
#define DATA 1
#define BSS  2

int load_protected_program(char *filename, NEWPROCESS * proc)
{
    FILEHDR	file_hdr;
    AOUTHDR	aout_hdr;
    SCNHDR	scnd_hdr[3];
    DWORD	tdbsegm, stacksegm;
    DWORD	headoff;
    UINT	stack32sel;
    int 	fhandle;
    int 	use_dpmi10;

    if ((fhandle = rm_open(filename, RM_O_RDONLY | RM_O_DENYWR)) == -1)
	return doserror_to_errno(_doserrno);

    /* skip exe-header, return correct offset in file */
    headoff = 0;
    skip_exe_hdr(fhandle, &headoff, proc);

    /* read file header */
    rm_read(fhandle, &file_hdr, sizeof(file_hdr));

    if (file_hdr.f_magic == 0x14C) {	/* COFF header */
	rm_read(fhandle, &aout_hdr, sizeof(aout_hdr));
	rm_lseek(fhandle, headoff + sizeof(file_hdr) + file_hdr.f_opthdr, 0);
	rm_read(fhandle, scnd_hdr, sizeof(scnd_hdr));
	if ((scnd_hdr[TEXT].s_scnptr & 0xFF) == 0xA8) { /* DJGPP */
	    scnd_hdr[TEXT].s_vaddr &= ~0xFFL;
	    scnd_hdr[TEXT].s_scnptr &= ~0xFFL;	    /* align */
	    scnd_hdr[TEXT].s_size += 0xa8L;
	    proc->p_flags |= PF_DJGPP_FILE;
	}
	else {
	    DWORD image_base;
	    rm_lseek(fhandle, headoff + sizeof(file_hdr) + file_hdr.f_opthdr, 0);
	    rm_read(fhandle, &image_base, 4);
	    if (image_base == 0x400000L)
		proc->p_flags |= PF_TNT_FILE;
	    printf("image base %lX\n", image_base);
	}
    }
    else if (file_hdr.f_magic == 0x10B) {
	GNUOUT gnu_hdr;
	rm_lseek(fhandle, headoff, 0);
	rm_read(fhandle, &gnu_hdr, sizeof(gnu_hdr));

	aout_hdr.magic = 0x10B;
	aout_hdr.tsize = gnu_hdr.a_text;
	aout_hdr.dsize = gnu_hdr.a_data;
	aout_hdr.bsize = gnu_hdr.a_bss;
	aout_hdr.entry = gnu_hdr.a_entry;

	scnd_hdr[TEXT].s_size = gnu_hdr.a_text;
	scnd_hdr[DATA].s_size = gnu_hdr.a_data;
	scnd_hdr[BSS].s_size = gnu_hdr.a_bss;

	if (gnu_hdr.a_entry == 0x10000L) {   /* EMX STYLE */
	    scnd_hdr[TEXT].s_vaddr = 0x10000L;
	    scnd_hdr[DATA].s_vaddr =
		0x10000L + ((gnu_hdr.a_text + 0xFFFFL) & ~0xFFFFL);
	    scnd_hdr[BSS].s_vaddr =
		scnd_hdr[DATA].s_vaddr + gnu_hdr.a_data;
	    scnd_hdr[TEXT].s_scnptr = 1024;
	    scnd_hdr[DATA].s_scnptr = 1024 + gnu_hdr.a_text;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -