mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-26 16:37:30 +03:00
PE loader. link with required dll
git-svn-id: svn://kolibrios.org@892 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ef9256f6b0
commit
c6b57fbd1a
@ -1,105 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
set languages=en ru ge et
|
|
||||||
set drivers=sound sis infinity ensoniq ps2mouse com_mouse uart ati2d vmode
|
|
||||||
set targets=all kernel drivers skins clean
|
|
||||||
|
|
||||||
call :Check_Target %1
|
|
||||||
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
|
|
||||||
call :Target_%target%
|
|
||||||
|
|
||||||
if ERRORLEVEL 0 goto Exit_OK
|
|
||||||
|
|
||||||
echo There was an error executing script.
|
|
||||||
echo For any help, please send a report.
|
|
||||||
pause
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:Check_Lang
|
|
||||||
set res=%1
|
|
||||||
:Check_Lang_loop
|
|
||||||
for %%a in (%languages%) do if %%a==%res% set lang=%res%
|
|
||||||
if defined lang goto :eof
|
|
||||||
|
|
||||||
echo Language '%res%' is incorrect
|
|
||||||
echo Enter valid language [ %languages% ]:
|
|
||||||
|
|
||||||
set /P res=">
|
|
||||||
goto Check_Lang_loop
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
:Check_Target
|
|
||||||
set res=%1
|
|
||||||
:Check_Target_loop
|
|
||||||
for %%a in (%targets%) do if %%a==%res% set target=%res%
|
|
||||||
if defined target goto :eof
|
|
||||||
|
|
||||||
echo Target '%res%' is incorrect
|
|
||||||
echo Enter valid target [ %targets% ]:
|
|
||||||
|
|
||||||
set /P res=">
|
|
||||||
goto Check_Target_loop
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_kernel
|
|
||||||
echo *** building kernel with language '%lang%' ...
|
|
||||||
|
|
||||||
if not exist bin mkdir bin
|
|
||||||
echo lang fix %lang% > lang.inc
|
|
||||||
fasm -m 65536 kernel.asm bin\kernel.mnt
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
erase lang.inc
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_all
|
|
||||||
call :Target_kernel
|
|
||||||
call :Target_drivers
|
|
||||||
call :Target_skins
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_drivers
|
|
||||||
echo *** building drivers ...
|
|
||||||
|
|
||||||
if not exist bin\drivers mkdir bin\drivers
|
|
||||||
cd drivers
|
|
||||||
for %%a in (%drivers%) do (
|
|
||||||
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
)
|
|
||||||
cd ..
|
|
||||||
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_skins
|
|
||||||
echo *** building skins ...
|
|
||||||
|
|
||||||
if not exist bin\skins mkdir bin\skins
|
|
||||||
cd skin
|
|
||||||
fasm -m 65536 default.asm ..\bin\skins\default.skn
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
cd ..
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
:Target_clean
|
|
||||||
echo *** cleaning ...
|
|
||||||
rmdir /S /Q bin
|
|
||||||
goto :Exit_OK
|
|
||||||
|
|
||||||
|
|
||||||
:Error_FasmFailed
|
|
||||||
echo error: fasm execution failed
|
|
||||||
erase lang.inc
|
|
||||||
pause
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
:Exit_OK
|
|
||||||
echo all operations has been done
|
|
||||||
pause
|
|
||||||
exit 0
|
|
@ -5,244 +5,75 @@
|
|||||||
#include <link.h>
|
#include <link.h>
|
||||||
#include <mm.h>
|
#include <mm.h>
|
||||||
#include <slab.h>
|
#include <slab.h>
|
||||||
|
#include <pe.h>
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned int DWORD;
|
|
||||||
typedef unsigned int LONG;
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
#define IMAGE_DOS_SIGNATURE 0x5A4D
|
|
||||||
#define IMAGE_NT_SIGNATURE 0x00004550
|
|
||||||
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
|
||||||
|
|
||||||
#pragma pack(push,2)
|
|
||||||
typedef struct _IMAGE_DOS_HEADER
|
|
||||||
{
|
|
||||||
WORD e_magic;
|
|
||||||
WORD e_cblp;
|
|
||||||
WORD e_cp;
|
|
||||||
WORD e_crlc;
|
|
||||||
WORD e_cparhdr;
|
|
||||||
WORD e_minalloc;
|
|
||||||
WORD e_maxalloc;
|
|
||||||
WORD e_ss;
|
|
||||||
WORD e_sp;
|
|
||||||
WORD e_csum;
|
|
||||||
WORD e_ip;
|
|
||||||
WORD e_cs;
|
|
||||||
WORD e_lfarlc;
|
|
||||||
WORD e_ovno;
|
|
||||||
WORD e_res[4];
|
|
||||||
WORD e_oemid;
|
|
||||||
WORD e_oeminfo;
|
|
||||||
WORD e_res2[10];
|
|
||||||
LONG e_lfanew;
|
|
||||||
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push,4)
|
|
||||||
typedef struct _IMAGE_FILE_HEADER
|
|
||||||
{
|
|
||||||
WORD Machine;
|
|
||||||
WORD NumberOfSections;
|
|
||||||
DWORD TimeDateStamp;
|
|
||||||
DWORD PointerToSymbolTable;
|
|
||||||
DWORD NumberOfSymbols;
|
|
||||||
WORD SizeOfOptionalHeader;
|
|
||||||
WORD Characteristics;
|
|
||||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
|
||||||
|
|
||||||
typedef struct _IMAGE_DATA_DIRECTORY {
|
|
||||||
DWORD VirtualAddress;
|
|
||||||
DWORD Size;
|
|
||||||
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
|
|
||||||
|
|
||||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
|
||||||
|
|
||||||
typedef struct _IMAGE_OPTIONAL_HEADER {
|
|
||||||
WORD Magic;
|
|
||||||
BYTE MajorLinkerVersion;
|
|
||||||
BYTE MinorLinkerVersion;
|
|
||||||
DWORD SizeOfCode;
|
|
||||||
DWORD SizeOfInitializedData;
|
|
||||||
DWORD SizeOfUninitializedData;
|
|
||||||
DWORD AddressOfEntryPoint;
|
|
||||||
DWORD BaseOfCode;
|
|
||||||
DWORD BaseOfData;
|
|
||||||
DWORD ImageBase;
|
|
||||||
DWORD SectionAlignment;
|
|
||||||
DWORD FileAlignment;
|
|
||||||
WORD MajorOperatingSystemVersion;
|
|
||||||
WORD MinorOperatingSystemVersion;
|
|
||||||
WORD MajorImageVersion;
|
|
||||||
WORD MinorImageVersion;
|
|
||||||
WORD MajorSubsystemVersion;
|
|
||||||
WORD MinorSubsystemVersion;
|
|
||||||
DWORD Win32VersionValue;
|
|
||||||
DWORD SizeOfImage;
|
|
||||||
DWORD SizeOfHeaders;
|
|
||||||
DWORD CheckSum;
|
|
||||||
WORD Subsystem;
|
|
||||||
WORD DllCharacteristics;
|
|
||||||
DWORD SizeOfStackReserve;
|
|
||||||
DWORD SizeOfStackCommit;
|
|
||||||
DWORD SizeOfHeapReserve;
|
|
||||||
DWORD SizeOfHeapCommit;
|
|
||||||
DWORD LoaderFlags;
|
|
||||||
DWORD NumberOfRvaAndSizes;
|
|
||||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
|
||||||
} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push,4)
|
|
||||||
typedef struct _IMAGE_NT_HEADERS
|
|
||||||
{
|
|
||||||
DWORD Signature;
|
|
||||||
IMAGE_FILE_HEADER FileHeader;
|
|
||||||
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
|
||||||
} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
|
|
||||||
|
|
||||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
|
||||||
|
|
||||||
typedef struct _IMAGE_SECTION_HEADER
|
|
||||||
{
|
|
||||||
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
|
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD PhysicalAddress;
|
|
||||||
DWORD VirtualSize;
|
|
||||||
} Misc;
|
|
||||||
DWORD VirtualAddress;
|
|
||||||
DWORD SizeOfRawData;
|
|
||||||
DWORD PointerToRawData;
|
|
||||||
DWORD PointerToRelocations;
|
|
||||||
DWORD PointerToLinenumbers;
|
|
||||||
WORD NumberOfRelocations;
|
|
||||||
WORD NumberOfLinenumbers;
|
|
||||||
DWORD Characteristics;
|
|
||||||
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#pragma pack(push,4)
|
|
||||||
typedef struct _IMAGE_BASE_RELOCATION {
|
|
||||||
DWORD VirtualAddress;
|
|
||||||
DWORD SizeOfBlock;
|
|
||||||
} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
typedef struct _IMAGE_IMPORT_DESCRIPTOR
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD Characteristics;
|
|
||||||
DWORD OriginalFirstThunk;
|
|
||||||
};
|
|
||||||
DWORD TimeDateStamp;
|
|
||||||
DWORD ForwarderChain;
|
|
||||||
DWORD Name;
|
|
||||||
DWORD FirstThunk;
|
|
||||||
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
|
|
||||||
|
|
||||||
typedef struct _IMAGE_THUNK_DATA32
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD ForwarderString;
|
|
||||||
DWORD Function;
|
|
||||||
DWORD Ordinal;
|
|
||||||
DWORD AddressOfData;
|
|
||||||
} u1;
|
|
||||||
} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
|
|
||||||
|
|
||||||
typedef struct _IMAGE_IMPORT_BY_NAME
|
|
||||||
{
|
|
||||||
WORD Hint;
|
|
||||||
BYTE Name[1];
|
|
||||||
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
|
|
||||||
|
|
||||||
#define IMAGE_ORDINAL_FLAG 0x80000000
|
|
||||||
|
|
||||||
typedef struct _IMAGE_EXPORT_DIRECTORY {
|
|
||||||
DWORD Characteristics;
|
|
||||||
DWORD TimeDateStamp;
|
|
||||||
WORD MajorVersion;
|
|
||||||
WORD MinorVersion;
|
|
||||||
DWORD Name;
|
|
||||||
DWORD Base;
|
|
||||||
DWORD NumberOfFunctions;
|
|
||||||
DWORD NumberOfNames;
|
|
||||||
DWORD AddressOfFunctions;
|
|
||||||
DWORD AddressOfNames;
|
|
||||||
DWORD AddressOfNameOrdinals;
|
|
||||||
} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
|
|
||||||
|
|
||||||
//extern IMAGE_EXPORT_DIRECTORY kernel_exports;
|
|
||||||
|
|
||||||
#define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addValue) )
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
addr_t base;
|
|
||||||
addr_t frame;
|
|
||||||
md_t *md;
|
|
||||||
|
|
||||||
IMAGE_OPTIONAL_HEADER *opthdr;
|
|
||||||
|
|
||||||
}dll_t;
|
|
||||||
|
|
||||||
static inline bool IsPowerOf2(u32_t val)
|
|
||||||
{
|
|
||||||
if(val == 0)
|
|
||||||
return false;
|
|
||||||
return (val & (val - 1)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void sec_copy(void *dst, const void *src, size_t len)
|
|
||||||
{
|
|
||||||
u32_t tmp;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"shrl $2, %%ecx \n\t"
|
|
||||||
"rep movsl"
|
|
||||||
:"=c"(tmp),"=S"(tmp),"=D"(tmp)
|
|
||||||
:"c"(len),"S"(src),"D"(dst)
|
|
||||||
:"cc");
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void sec_clear(void *dst, size_t len)
|
|
||||||
{
|
|
||||||
u32_t tmp;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"xorl %%eax, %%eax \n\t"
|
|
||||||
"rep stosb"
|
|
||||||
:"=c"(tmp),"=D"(tmp)
|
|
||||||
:"c"(len),"D"(dst)
|
|
||||||
:"eax","cc");
|
|
||||||
};
|
|
||||||
|
|
||||||
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
|
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
|
||||||
|
static dll_t core_dll;
|
||||||
|
|
||||||
void __export create_image(void *img_base, void *image) asm ("CreateImage");
|
static char* strupr(char *str )
|
||||||
|
|
||||||
md_t* __fastcall load_image(const char *path);
|
|
||||||
|
|
||||||
|
|
||||||
void* __fastcall load_pe(const char *path)
|
|
||||||
{
|
{
|
||||||
md_t *md;
|
char *p;
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
md = load_image(path);
|
p = str;
|
||||||
|
while( (c = *p) )
|
||||||
|
{
|
||||||
|
if( c >= 'a' && c <= 'z' )
|
||||||
|
*p = c - 'a' + 'A';
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
if( md )
|
return( str );
|
||||||
return (void*)md->base;
|
}
|
||||||
|
|
||||||
|
void init_core_dll()
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dos;
|
||||||
|
PIMAGE_NT_HEADERS32 nt;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY exp;
|
||||||
|
|
||||||
|
dos = (PIMAGE_DOS_HEADER)LOAD_BASE;
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
|
||||||
|
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||||
|
|
||||||
|
list_initialize(&core_dll.link);
|
||||||
|
|
||||||
|
core_dll.img_base = LOAD_BASE;
|
||||||
|
core_dll.img_size = nt->OptionalHeader.SizeOfImage;
|
||||||
|
core_dll.img_md = NULL;
|
||||||
|
|
||||||
|
core_dll.img_hdr = nt;
|
||||||
|
core_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
|
||||||
|
core_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
|
||||||
|
nt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||||
|
core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name));
|
||||||
|
|
||||||
|
DBG("%s base %x size %x sections %d exports %x\n",
|
||||||
|
core_dll.img_name, core_dll.img_base,
|
||||||
|
core_dll.img_size, nt->FileHeader.NumberOfSections,
|
||||||
|
core_dll.img_exp );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
dll_t * find_dll(const char *name)
|
||||||
|
{
|
||||||
|
dll_t* dll = &core_dll;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if( !strncmp(name,dll->img_name,16))
|
||||||
|
return dll;
|
||||||
|
|
||||||
|
dll = (dll_t*)dll->link.next;
|
||||||
|
|
||||||
|
}while(&dll->link != &core_dll.link);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char srv_name[16]; // ASCIIZ string
|
char srv_name[16]; // ASCIIZ string
|
||||||
@ -271,418 +102,25 @@ srv_t* __fastcall load_pe_driver(const char *path)
|
|||||||
if( ! md )
|
if( ! md )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dos = (PIMAGE_DOS_HEADER)md->base;
|
if( link_image( md->base ) )
|
||||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
{
|
||||||
|
dos = (PIMAGE_DOS_HEADER)md->base;
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
drv_entry = MakePtr(drv_entry_t*, md->base,
|
drv_entry = MakePtr(drv_entry_t*, md->base,
|
||||||
nt->OptionalHeader.AddressOfEntryPoint);
|
nt->OptionalHeader.AddressOfEntryPoint);
|
||||||
|
|
||||||
srv = drv_entry(1);
|
srv = drv_entry(1);
|
||||||
|
|
||||||
if(srv != NULL)
|
if(srv != NULL)
|
||||||
srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base;
|
srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base;
|
||||||
|
|
||||||
return srv;
|
return srv;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
md_free( md );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
md_t* __fastcall load_image(const char *path)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER dos;
|
|
||||||
PIMAGE_NT_HEADERS32 nt;
|
|
||||||
|
|
||||||
md_t *img_md;
|
|
||||||
|
|
||||||
size_t img_size;
|
|
||||||
void *img_base;
|
|
||||||
count_t img_pages;
|
|
||||||
|
|
||||||
size_t raw_size = 0;
|
|
||||||
void *raw;
|
|
||||||
|
|
||||||
// void *image;
|
|
||||||
|
|
||||||
DBG("load file %s\n", path);
|
|
||||||
|
|
||||||
raw = load_file(path, &raw_size);
|
|
||||||
|
|
||||||
DBG("raw = %x\n\n", raw);
|
|
||||||
|
|
||||||
dos = (PIMAGE_DOS_HEADER)raw;
|
|
||||||
|
|
||||||
if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
|
||||||
|
|
||||||
if( (addr_t)nt < (addr_t)raw)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(nt->Signature != IMAGE_NT_SIGNATURE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE)
|
|
||||||
{
|
|
||||||
if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) ||
|
|
||||||
!IsPowerOf2(nt->OptionalHeader.FileAlignment))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(nt->FileHeader.NumberOfSections > 96)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
img_size = nt->OptionalHeader.SizeOfImage;
|
|
||||||
// img_pages = img_size / PAGE_SIZE;
|
|
||||||
|
|
||||||
img_md = md_alloc(img_size, PG_SW);
|
|
||||||
|
|
||||||
|
|
||||||
if( !img_md)
|
|
||||||
{
|
|
||||||
mem_free(raw);
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
|
|
||||||
img_base = (void*)img_md->base;
|
|
||||||
|
|
||||||
create_image(img_base, raw);
|
|
||||||
|
|
||||||
mem_free(raw);
|
|
||||||
|
|
||||||
// dos = (PIMAGE_DOS_HEADER)img_base;
|
|
||||||
// nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
|
||||||
|
|
||||||
return img_md;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
addr_t get_proc_addr(addr_t module, char *name)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER expdos;
|
|
||||||
PIMAGE_NT_HEADERS32 expnt;
|
|
||||||
PIMAGE_EXPORT_DIRECTORY exp;
|
|
||||||
u32_t *functions;
|
|
||||||
char **funcname;
|
|
||||||
int ind;
|
|
||||||
|
|
||||||
expdos = (PIMAGE_DOS_HEADER)module;
|
|
||||||
expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew);
|
|
||||||
|
|
||||||
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,module,
|
|
||||||
expnt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
|
||||||
|
|
||||||
functions = MakePtr(DWORD*,exp->AddressOfFunctions,module);
|
|
||||||
funcname = MakePtr(char**,exp->AddressOfNames,module);
|
|
||||||
|
|
||||||
for(ind=0; *funcname;funcname++,ind++)
|
|
||||||
{
|
|
||||||
if(!strcmp(name,MakePtr(char*,*funcname,module)))
|
|
||||||
return functions[ind] + module;
|
|
||||||
};
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
void create_image(void *img_base, void *image)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER dos;
|
|
||||||
PIMAGE_NT_HEADERS32 nt;
|
|
||||||
PIMAGE_SECTION_HEADER img_sec;
|
|
||||||
|
|
||||||
u32_t sec_align;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
|
|
||||||
/* assumed that image is valid */
|
|
||||||
|
|
||||||
dos = (PIMAGE_DOS_HEADER)image;
|
|
||||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
|
||||||
|
|
||||||
sec_copy(img_base,image,nt->OptionalHeader.SizeOfHeaders);
|
|
||||||
|
|
||||||
img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32));
|
|
||||||
|
|
||||||
sec_align = nt->OptionalHeader.SectionAlignment;
|
|
||||||
|
|
||||||
for(i=0; i< nt->FileHeader.NumberOfSections; i++)
|
|
||||||
{
|
|
||||||
char *src_ptr;
|
|
||||||
char *dest_ptr;
|
|
||||||
size_t sec_size;
|
|
||||||
|
|
||||||
src_ptr = MakePtr(char*, image, img_sec->PointerToRawData);
|
|
||||||
dest_ptr = MakePtr(char*,img_base, img_sec->VirtualAddress);
|
|
||||||
|
|
||||||
if(img_sec->SizeOfRawData)
|
|
||||||
sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
|
|
||||||
|
|
||||||
sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align;
|
|
||||||
|
|
||||||
if(sec_size > img_sec->SizeOfRawData)
|
|
||||||
sec_clear(dest_ptr + img_sec->SizeOfRawData,
|
|
||||||
sec_size - img_sec->SizeOfRawData);
|
|
||||||
img_sec++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nt->OptionalHeader.DataDirectory[5].Size)
|
|
||||||
{
|
|
||||||
PIMAGE_BASE_RELOCATION reloc;
|
|
||||||
|
|
||||||
/* FIXME addr_t */
|
|
||||||
|
|
||||||
u32_t delta = (u32_t)img_base - nt->OptionalHeader.ImageBase;
|
|
||||||
|
|
||||||
reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base,
|
|
||||||
nt->OptionalHeader.DataDirectory[5].VirtualAddress);
|
|
||||||
|
|
||||||
while ( reloc->SizeOfBlock != 0 )
|
|
||||||
{
|
|
||||||
u32_t cnt;
|
|
||||||
u16_t *entry;
|
|
||||||
u16_t reltype;
|
|
||||||
u32_t offs;
|
|
||||||
|
|
||||||
cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(u16_t);
|
|
||||||
entry = MakePtr( u16_t*, reloc, sizeof(*reloc) );
|
|
||||||
|
|
||||||
for ( i=0; i < cnt; i++ )
|
|
||||||
{
|
|
||||||
u16_t *p16;
|
|
||||||
u32_t *p32;
|
|
||||||
|
|
||||||
reltype = (*entry & 0xF000) >> 12;
|
|
||||||
offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
|
|
||||||
switch(reltype)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
p16 = MakePtr(u16_t*, img_base, offs);
|
|
||||||
*p16+= (u16_t)(delta>>16);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
p16 = MakePtr(u16_t*, img_base, offs);
|
|
||||||
*p16+= (u16_t)delta;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
p32 = MakePtr(u32_t*, img_base, offs);
|
|
||||||
*p32+= delta;
|
|
||||||
}
|
|
||||||
entry++;
|
|
||||||
}
|
|
||||||
reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if(nt->OptionalHeader.DataDirectory[1].Size)
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR imp;
|
|
||||||
|
|
||||||
int warn = 0;
|
|
||||||
|
|
||||||
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
|
|
||||||
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while ( 1 )
|
|
||||||
{
|
|
||||||
PIMAGE_THUNK_DATA32 thunk;
|
|
||||||
|
|
||||||
PIMAGE_DOS_HEADER expdos;
|
|
||||||
PIMAGE_NT_HEADERS32 expnt;
|
|
||||||
PIMAGE_EXPORT_DIRECTORY exp;
|
|
||||||
|
|
||||||
u32_t *iat;
|
|
||||||
char *libname;
|
|
||||||
addr_t *functions;
|
|
||||||
u16_t *ordinals;
|
|
||||||
char **funcname;
|
|
||||||
|
|
||||||
|
|
||||||
if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
libname=MakePtr(char*,imp->Name, img_base);
|
|
||||||
|
|
||||||
DBG("import from %s\n",libname);
|
|
||||||
|
|
||||||
expdos = (PIMAGE_DOS_HEADER)IMAGE_BASE;
|
|
||||||
expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew);
|
|
||||||
|
|
||||||
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
|
|
||||||
expnt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
|
||||||
|
|
||||||
functions = MakePtr(DWORD*,exp->AddressOfFunctions,LOAD_BASE);
|
|
||||||
ordinals = MakePtr(WORD*, exp->AddressOfNameOrdinals,LOAD_BASE);
|
|
||||||
funcname = MakePtr(char**, exp->AddressOfNames,LOAD_BASE);
|
|
||||||
|
|
||||||
thunk = MakePtr(PIMAGE_THUNK_DATA32,
|
|
||||||
imp->Characteristics, img_base);
|
|
||||||
iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
|
|
||||||
|
|
||||||
while ( 1 ) // Loop forever (or until we break out)
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_BY_NAME ord;
|
|
||||||
addr_t addr;
|
|
||||||
|
|
||||||
if ( thunk->u1.AddressOfData == 0 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
|
|
||||||
{
|
|
||||||
// printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
|
|
||||||
thunk->u1.AddressOfData, img_base);
|
|
||||||
*iat=0;
|
|
||||||
|
|
||||||
DBG("import %s", ord->Name);
|
|
||||||
|
|
||||||
if(strncmp(ord->Name,
|
|
||||||
MakePtr(char*,funcname[ord->Hint],LOAD_BASE),32))
|
|
||||||
{
|
|
||||||
int ind;
|
|
||||||
char **names=funcname;
|
|
||||||
|
|
||||||
for(names = funcname,ind = 0;
|
|
||||||
ind < exp->NumberOfNames; names++,ind++)
|
|
||||||
{
|
|
||||||
if(!strncmp(ord->Name,MakePtr(char*,*names,LOAD_BASE),32))
|
|
||||||
{
|
|
||||||
DBG(" \tat %x\n", functions[ind] + LOAD_BASE);
|
|
||||||
*iat = functions[ind] + LOAD_BASE;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if(ind == exp->NumberOfNames)
|
|
||||||
{
|
|
||||||
DBG(" unresolved import %s\n",ord->Name);
|
|
||||||
warn=1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG(" \tat %x\n", functions[ord->Hint] + LOAD_BASE);
|
|
||||||
*iat = functions[ord->Hint] + LOAD_BASE;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
thunk++; // Advance to next thunk
|
|
||||||
iat++;
|
|
||||||
}
|
|
||||||
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
DBG("\ncreate pe base %x, size %x, %d sections\n\n",img_base,
|
|
||||||
nt->OptionalHeader.SizeOfImage, nt->FileHeader.NumberOfSections);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
u32 map_PE(u32 base, void *image)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER dos;
|
|
||||||
PIMAGE_NT_HEADERS32 nt;
|
|
||||||
PIMAGE_SECTION_HEADER sec;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int pages;
|
|
||||||
|
|
||||||
dos = (PIMAGE_DOS_HEADER)image;
|
|
||||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
|
||||||
|
|
||||||
|
|
||||||
img_size = nt->OptionalHeader.SizeOfImage;
|
|
||||||
img_pages = img_size / PAGE_SIZE;
|
|
||||||
|
|
||||||
img_md = md_alloc(img_size, PG_SW);
|
|
||||||
|
|
||||||
if( !img_md)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
scopy(base,(u32)image,nt->OptionalHeader.SizeOfHeaders);
|
|
||||||
|
|
||||||
sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32));
|
|
||||||
|
|
||||||
|
|
||||||
if(nt->OptionalHeader.DataDirectory[1].Size)
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR imp;
|
|
||||||
|
|
||||||
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR,base,
|
|
||||||
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
|
|
||||||
while ( 1 )
|
|
||||||
{
|
|
||||||
PIMAGE_THUNK_DATA32 thunk;
|
|
||||||
u32 *iat;
|
|
||||||
char *libname;
|
|
||||||
|
|
||||||
if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
thunk = MakePtr(PIMAGE_THUNK_DATA32,
|
|
||||||
imp->Characteristics, base);
|
|
||||||
iat= MakePtr(DWORD*,imp->FirstThunk, base);
|
|
||||||
|
|
||||||
while ( 1 ) // Loop forever (or until we break out)
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_BY_NAME ord;
|
|
||||||
|
|
||||||
u32 addr;
|
|
||||||
|
|
||||||
if ( thunk->u1.AddressOfData == 0 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
|
|
||||||
{
|
|
||||||
// printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PKERNEL_EXPORT exp;
|
|
||||||
exp = kernel_export;
|
|
||||||
|
|
||||||
ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
|
|
||||||
thunk->u1.AddressOfData,base);
|
|
||||||
*iat=-1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(!strncmp(ord->Name,exp->name,16))
|
|
||||||
{
|
|
||||||
*iat = exp->address;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
exp++;
|
|
||||||
} while(exp->name != 0);
|
|
||||||
};
|
|
||||||
thunk++; // Advance to next thunk
|
|
||||||
iat++;
|
|
||||||
}
|
|
||||||
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
@ -3,24 +3,24 @@
|
|||||||
|
|
||||||
|
|
||||||
.section .drectve
|
.section .drectve
|
||||||
.ascii " -export:CreateImage"
|
.ascii " -export:CreateImage" # cdecl
|
||||||
.ascii " -export:LoadFile"
|
.ascii " -export:LoadFile" # stdcall
|
||||||
|
|
||||||
.ascii " -export:Kmalloc" #
|
.ascii " -export:Kmalloc" # eax FIXME
|
||||||
.ascii " -export:Kfree" #
|
.ascii " -export:Kfree" # eax FIXME
|
||||||
|
|
||||||
.ascii " -export:UserAlloc" # stdcall
|
.ascii " -export:UserAlloc" # stdcall
|
||||||
.ascii " -export:UserFree" # stdcall
|
.ascii " -export:UserFree" # stdcall
|
||||||
|
|
||||||
|
.ascii " -export:GetPgAddr" # eax FIXME
|
||||||
.ascii " -export:MapIoMem" # stdcall
|
.ascii " -export:MapIoMem" # stdcall
|
||||||
.ascii " -export:GetPgAddr" # eax
|
|
||||||
.ascii " -export:CreateObject" #
|
|
||||||
.ascii " -export:DestroyObject" #
|
|
||||||
.ascii " -export:CreateRingBuffer" # stdcall
|
.ascii " -export:CreateRingBuffer" # stdcall
|
||||||
.ascii " -export:CommitPages" # eax, ebx, ecx
|
.ascii " -export:CommitPages" # eax, ebx, ecx FIXME
|
||||||
|
.ascii " -export:UnmapPages" # eax, ecx FIXME
|
||||||
|
.ascii " -export:CreateObject" # eax, ebx FIXME
|
||||||
|
.ascii " -export:DestroyObject" # eax
|
||||||
|
|
||||||
.ascii " -export:RegService" # stdcall
|
.ascii " -export:RegService" # stdcall
|
||||||
.ascii " -export:UnmapPages" # eax, ecx
|
|
||||||
.ascii " -export:SysMsgBoardStr" #
|
.ascii " -export:SysMsgBoardStr" #
|
||||||
.ascii " -export:SetScreen" #
|
.ascii " -export:SetScreen" #
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ md_t* __fastcall find_large_md(size_t size)
|
|||||||
if(idx0 == 31)
|
if(idx0 == 31)
|
||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)lheap.unmapped[31].next;
|
md_t *tmp = (md_t*)lheap.unmapped[31].next;
|
||||||
while((link_t*)tmp != &lheap.unmapped[31])
|
while(&tmp->link != &lheap.unmapped[31])
|
||||||
{
|
{
|
||||||
if(tmp->size >= size)
|
if(tmp->size >= size)
|
||||||
{
|
{
|
||||||
@ -193,7 +193,7 @@ md_t* __fastcall find_unmapped_md(size_t size)
|
|||||||
ASSERT( !list_empty(&sheap.unmapped[31]));
|
ASSERT( !list_empty(&sheap.unmapped[31]));
|
||||||
|
|
||||||
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
||||||
while((link_t*)tmp != &sheap.unmapped[31])
|
while( &tmp->link != &sheap.unmapped[31])
|
||||||
{
|
{
|
||||||
if(tmp->size >= size)
|
if(tmp->size >= size)
|
||||||
{
|
{
|
||||||
@ -283,7 +283,7 @@ md_t* __fastcall find_unmapped_md(size_t size)
|
|||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.unmapped[31])
|
while( &tmp->link != &sheap.unmapped[31])
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -333,7 +333,7 @@ md_t* __fastcall find_mapped_md(size_t size)
|
|||||||
ASSERT( !list_empty(&sheap.mapped[31]));
|
ASSERT( !list_empty(&sheap.mapped[31]));
|
||||||
|
|
||||||
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
||||||
while((link_t*)tmp != &sheap.mapped[31])
|
while( &tmp->link != &sheap.mapped[31])
|
||||||
{
|
{
|
||||||
if(tmp->size >= size)
|
if(tmp->size >= size)
|
||||||
{
|
{
|
||||||
@ -437,7 +437,7 @@ md_t* __fastcall find_mapped_md(size_t size)
|
|||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.mapped[31])
|
while( &tmp->link != &sheap.mapped[31])
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -521,7 +521,7 @@ void __fastcall free_unmapped_md(md_t *md)
|
|||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
md_t *tmp = (md_t*)sheap.unmapped[31].next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.unmapped[31])
|
while( &tmp->link != &sheap.unmapped[31])
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -598,7 +598,7 @@ void __fastcall free_mapped_md(md_t *md)
|
|||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
md_t *tmp = (md_t*)sheap.mapped[31].next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.mapped[31])
|
while( &tmp->link != &sheap.mapped[31])
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -663,6 +663,44 @@ md_t* __fastcall md_alloc(size_t size, u32_t flags)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void __fastcall md_free(md_t *md)
|
||||||
|
{
|
||||||
|
|
||||||
|
if( md )
|
||||||
|
{
|
||||||
|
md_t *lmd;
|
||||||
|
|
||||||
|
DBG("free md: %x base: %x size: %x\n",md, md->base, md->size);
|
||||||
|
|
||||||
|
ASSERT(md->state == MD_USED);
|
||||||
|
|
||||||
|
list_remove((link_t*)md);
|
||||||
|
|
||||||
|
lmd = (md_t*)md->parent;
|
||||||
|
|
||||||
|
ASSERT(lmd != 0);
|
||||||
|
|
||||||
|
if(lmd->parent != 0)
|
||||||
|
{
|
||||||
|
addr_t mem = md->base;
|
||||||
|
addr_t *pte = &((addr_t*)page_tabs)[md->base>>12];
|
||||||
|
count_t tmp = md->size >> 12;
|
||||||
|
|
||||||
|
while(tmp--)
|
||||||
|
{
|
||||||
|
*pte++ = 0;
|
||||||
|
asm volatile ( "invlpg (%0)" ::"r" (mem) );
|
||||||
|
mem+= 4096;
|
||||||
|
};
|
||||||
|
free_mapped_md( md );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free_unmapped_md( md );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
void * __fastcall mem_alloc(size_t size, u32_t flags)
|
void * __fastcall mem_alloc(size_t size, u32_t flags)
|
||||||
{
|
{
|
||||||
eflags_t efl;
|
eflags_t efl;
|
||||||
@ -687,7 +725,7 @@ void * __fastcall mem_alloc(size_t size, u32_t flags)
|
|||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.used.next;
|
md_t *tmp = (md_t*)sheap.used.next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.used)
|
while( &tmp->link != &sheap.used)
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -720,7 +758,7 @@ void __fastcall mem_free(void *mem)
|
|||||||
|
|
||||||
tmp = (md_t*)sheap.used.next;
|
tmp = (md_t*)sheap.used.next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.used)
|
while( &tmp->link != &sheap.used)
|
||||||
{
|
{
|
||||||
if( tmp->base == (addr_t)mem )
|
if( tmp->base == (addr_t)mem )
|
||||||
{
|
{
|
||||||
@ -732,36 +770,8 @@ void __fastcall mem_free(void *mem)
|
|||||||
|
|
||||||
if( md )
|
if( md )
|
||||||
{
|
{
|
||||||
md_t *lmd;
|
md_free( md );
|
||||||
|
|
||||||
DBG("\tmd: %x base: %x size: %x\n",md, md->base, md->size);
|
|
||||||
|
|
||||||
ASSERT(md->state == MD_USED);
|
|
||||||
|
|
||||||
list_remove((link_t*)md);
|
|
||||||
|
|
||||||
lmd = (md_t*)md->parent;
|
|
||||||
|
|
||||||
ASSERT(lmd != 0);
|
|
||||||
|
|
||||||
if(lmd->parent != 0)
|
|
||||||
{
|
|
||||||
count_t tmp = md->size >> 12;
|
|
||||||
addr_t *pte = &((addr_t*)page_tabs)[md->base>>12];
|
|
||||||
|
|
||||||
while(tmp--)
|
|
||||||
{
|
|
||||||
*pte++ = 0;
|
|
||||||
asm volatile (
|
|
||||||
"invlpg (%0)"
|
|
||||||
::"r" (mem) );
|
|
||||||
mem+= 4096;
|
|
||||||
};
|
|
||||||
|
|
||||||
free_mapped_md( md );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
free_unmapped_md( md );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DBG("\tERROR: invalid base address: %x\n", mem);
|
DBG("\tERROR: invalid base address: %x\n", mem);
|
||||||
|
414
kernel/branches/kolibri_pe/core/pe.c
Normal file
414
kernel/branches/kolibri_pe/core/pe.c
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <core.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
#include <link.h>
|
||||||
|
#include <mm.h>
|
||||||
|
#include <slab.h>
|
||||||
|
#include <pe.h>
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool IsPowerOf2(u32_t val)
|
||||||
|
{
|
||||||
|
if(val == 0)
|
||||||
|
return false;
|
||||||
|
return (val & (val - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void sec_copy(addr_t dst, addr_t src, size_t len)
|
||||||
|
{
|
||||||
|
u32_t tmp;
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"shrl $2, %%ecx \n\t"
|
||||||
|
"rep movsl"
|
||||||
|
:"=c"(tmp),"=S"(tmp),"=D"(tmp)
|
||||||
|
:"c"(len),"S"(src),"D"(dst)
|
||||||
|
:"cc");
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void sec_clear(addr_t dst, size_t len)
|
||||||
|
{
|
||||||
|
u32_t tmp;
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"xorl %%eax, %%eax \n\t"
|
||||||
|
"rep stosb"
|
||||||
|
:"=c"(tmp),"=D"(tmp)
|
||||||
|
:"c"(len),"D"(dst)
|
||||||
|
:"eax","cc");
|
||||||
|
};
|
||||||
|
|
||||||
|
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
|
||||||
|
void __export create_image(addr_t img_base, addr_t raw) asm ("CreateImage");
|
||||||
|
bool link_image(addr_t img_base);
|
||||||
|
|
||||||
|
md_t* __fastcall load_image(const char *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
void* __fastcall load_pe(const char *path)
|
||||||
|
{
|
||||||
|
md_t *md;
|
||||||
|
|
||||||
|
md = load_image(path);
|
||||||
|
|
||||||
|
if( md )
|
||||||
|
return (void*)md->base;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool validate_pe(void *raw, size_t raw_size)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dos;
|
||||||
|
PIMAGE_NT_HEADERS32 nt;
|
||||||
|
|
||||||
|
dos = (PIMAGE_DOS_HEADER)raw;
|
||||||
|
|
||||||
|
if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
|
if( (addr_t)nt < (addr_t)raw)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(nt->Signature != IMAGE_NT_SIGNATURE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE)
|
||||||
|
{
|
||||||
|
if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) ||
|
||||||
|
!IsPowerOf2(nt->OptionalHeader.FileAlignment))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(nt->FileHeader.NumberOfSections > 96)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
md_t* __fastcall load_image(const char *path)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dos;
|
||||||
|
PIMAGE_NT_HEADERS32 nt;
|
||||||
|
|
||||||
|
md_t *img_md;
|
||||||
|
|
||||||
|
size_t img_size;
|
||||||
|
addr_t img_base;
|
||||||
|
count_t img_pages;
|
||||||
|
|
||||||
|
size_t raw_size = 0;
|
||||||
|
void *raw;
|
||||||
|
|
||||||
|
DBG("\nload image %s", path);
|
||||||
|
|
||||||
|
raw = load_file(path, &raw_size);
|
||||||
|
|
||||||
|
DBG(" raw = %x\n", raw);
|
||||||
|
|
||||||
|
if( ! raw)
|
||||||
|
{
|
||||||
|
DBG("file not found: %s\n", path);
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
if( ! validate_pe(raw, raw_size) )
|
||||||
|
{
|
||||||
|
DBG("invalid pe file %s\n", path);
|
||||||
|
mem_free(raw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dos = (PIMAGE_DOS_HEADER)raw;
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
|
img_size = nt->OptionalHeader.SizeOfImage;
|
||||||
|
|
||||||
|
img_md = md_alloc(img_size, PG_SW);
|
||||||
|
|
||||||
|
|
||||||
|
if( !img_md)
|
||||||
|
{
|
||||||
|
mem_free(raw);
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
img_base = img_md->base;
|
||||||
|
|
||||||
|
create_image(img_base, (addr_t)raw);
|
||||||
|
|
||||||
|
mem_free(raw);
|
||||||
|
|
||||||
|
// dos = (PIMAGE_DOS_HEADER)img_base;
|
||||||
|
// nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
|
return img_md;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
addr_t get_proc_addr(addr_t module, char *name)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER expdos;
|
||||||
|
PIMAGE_NT_HEADERS32 expnt;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY exp;
|
||||||
|
u32_t *functions;
|
||||||
|
char **funcname;
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
expdos = (PIMAGE_DOS_HEADER)module;
|
||||||
|
expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew);
|
||||||
|
|
||||||
|
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,module,
|
||||||
|
expnt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||||
|
|
||||||
|
functions = MakePtr(DWORD*,exp->AddressOfFunctions,module);
|
||||||
|
funcname = MakePtr(char**,exp->AddressOfNames,module);
|
||||||
|
|
||||||
|
for(ind=0; *funcname;funcname++,ind++)
|
||||||
|
{
|
||||||
|
if(!strcmp(name,MakePtr(char*,*funcname,module)))
|
||||||
|
return functions[ind] + module;
|
||||||
|
};
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void create_image(addr_t img_base, addr_t raw)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dos;
|
||||||
|
PIMAGE_NT_HEADERS32 nt;
|
||||||
|
PIMAGE_SECTION_HEADER img_sec;
|
||||||
|
|
||||||
|
u32_t sec_align;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
/* assumed that image is valid */
|
||||||
|
|
||||||
|
dos = (PIMAGE_DOS_HEADER)raw;
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
|
sec_copy(img_base, raw, nt->OptionalHeader.SizeOfHeaders);
|
||||||
|
|
||||||
|
img_sec = MakePtr(PIMAGE_SECTION_HEADER, nt, sizeof(IMAGE_NT_HEADERS32));
|
||||||
|
|
||||||
|
sec_align = nt->OptionalHeader.SectionAlignment;
|
||||||
|
|
||||||
|
for(i=0; i< nt->FileHeader.NumberOfSections; i++)
|
||||||
|
{
|
||||||
|
addr_t src_ptr;
|
||||||
|
addr_t dest_ptr;
|
||||||
|
size_t sec_size;
|
||||||
|
|
||||||
|
src_ptr = MakePtr(addr_t, raw, img_sec->PointerToRawData);
|
||||||
|
dest_ptr = MakePtr(addr_t,img_base, img_sec->VirtualAddress);
|
||||||
|
|
||||||
|
if(img_sec->SizeOfRawData)
|
||||||
|
sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
|
||||||
|
|
||||||
|
sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align;
|
||||||
|
|
||||||
|
if(sec_size > img_sec->SizeOfRawData)
|
||||||
|
sec_clear(dest_ptr + img_sec->SizeOfRawData,
|
||||||
|
sec_size - img_sec->SizeOfRawData);
|
||||||
|
img_sec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nt->OptionalHeader.DataDirectory[5].Size)
|
||||||
|
{
|
||||||
|
PIMAGE_BASE_RELOCATION reloc;
|
||||||
|
|
||||||
|
/* FIXME addr_t */
|
||||||
|
|
||||||
|
u32_t delta = (u32_t)img_base - nt->OptionalHeader.ImageBase;
|
||||||
|
|
||||||
|
reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base,
|
||||||
|
nt->OptionalHeader.DataDirectory[5].VirtualAddress);
|
||||||
|
|
||||||
|
while ( reloc->SizeOfBlock != 0 )
|
||||||
|
{
|
||||||
|
u32_t cnt;
|
||||||
|
u16_t *entry;
|
||||||
|
u16_t reltype;
|
||||||
|
u32_t offs;
|
||||||
|
|
||||||
|
cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(u16_t);
|
||||||
|
entry = MakePtr( u16_t*, reloc, sizeof(*reloc) );
|
||||||
|
|
||||||
|
for ( i=0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
u16_t *p16;
|
||||||
|
u32_t *p32;
|
||||||
|
|
||||||
|
reltype = (*entry & 0xF000) >> 12;
|
||||||
|
offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
|
||||||
|
switch(reltype)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
p16 = MakePtr(u16_t*, img_base, offs);
|
||||||
|
*p16+= (u16_t)(delta>>16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
p16 = MakePtr(u16_t*, img_base, offs);
|
||||||
|
*p16+= (u16_t)delta;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
p32 = MakePtr(u32_t*, img_base, offs);
|
||||||
|
*p32+= delta;
|
||||||
|
}
|
||||||
|
entry++;
|
||||||
|
}
|
||||||
|
reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DBG("\ncreate pe base %x, size %x, %d sections\n\n",img_base,
|
||||||
|
nt->OptionalHeader.SizeOfImage, nt->FileHeader.NumberOfSections);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool link_image(addr_t img_base)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dos;
|
||||||
|
PIMAGE_NT_HEADERS32 nt;
|
||||||
|
|
||||||
|
int warn = 0;
|
||||||
|
|
||||||
|
/* assumed that image is valid */
|
||||||
|
|
||||||
|
dos = (PIMAGE_DOS_HEADER)img_base;
|
||||||
|
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||||
|
|
||||||
|
if(nt->OptionalHeader.DataDirectory[1].Size)
|
||||||
|
{
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR imp;
|
||||||
|
|
||||||
|
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
|
||||||
|
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
PIMAGE_THUNK_DATA32 thunk;
|
||||||
|
|
||||||
|
PIMAGE_DOS_HEADER expdos;
|
||||||
|
PIMAGE_NT_HEADERS32 expnt;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY exp;
|
||||||
|
|
||||||
|
u32_t *iat;
|
||||||
|
char *libname;
|
||||||
|
addr_t *functions;
|
||||||
|
u16_t *ordinals;
|
||||||
|
char **funcname;
|
||||||
|
|
||||||
|
dll_t *exp_dll;
|
||||||
|
|
||||||
|
if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
libname=MakePtr(char*,imp->Name, img_base);
|
||||||
|
|
||||||
|
DBG("import from %s\n",libname);
|
||||||
|
|
||||||
|
exp_dll = find_dll(libname);
|
||||||
|
if(exp_dll != NULL)
|
||||||
|
{
|
||||||
|
DBG("find %s\n", exp_dll->img_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG("can't find %s\n", libname);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
exp = exp_dll->img_exp;
|
||||||
|
|
||||||
|
functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base);
|
||||||
|
ordinals = MakePtr(WORD*, exp->AddressOfNameOrdinals,exp_dll->img_base);
|
||||||
|
funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base);
|
||||||
|
|
||||||
|
thunk = MakePtr(PIMAGE_THUNK_DATA32,
|
||||||
|
imp->Characteristics, img_base);
|
||||||
|
iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
|
||||||
|
|
||||||
|
while ( 1 ) // Loop forever (or until we break out)
|
||||||
|
{
|
||||||
|
PIMAGE_IMPORT_BY_NAME ord;
|
||||||
|
addr_t addr;
|
||||||
|
|
||||||
|
if ( thunk->u1.AddressOfData == 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
|
||||||
|
{
|
||||||
|
// printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
|
||||||
|
thunk->u1.AddressOfData, img_base);
|
||||||
|
*iat=0;
|
||||||
|
|
||||||
|
DBG("import %s", ord->Name);
|
||||||
|
|
||||||
|
if(strncmp(ord->Name,
|
||||||
|
MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32))
|
||||||
|
{
|
||||||
|
int ind;
|
||||||
|
char **names=funcname;
|
||||||
|
|
||||||
|
for(names = funcname,ind = 0;
|
||||||
|
ind < exp->NumberOfNames; names++,ind++)
|
||||||
|
{
|
||||||
|
if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32))
|
||||||
|
{
|
||||||
|
DBG(" \tat %x\n", functions[ind] + exp_dll->img_base);
|
||||||
|
*iat = functions[ind] + exp_dll->img_base;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if(ind == exp->NumberOfNames)
|
||||||
|
{
|
||||||
|
DBG(" unresolved import %s\n",ord->Name);
|
||||||
|
warn=1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base);
|
||||||
|
*iat = functions[ord->Hint] + exp_dll->img_base;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
thunk++; // Advance to next thunk
|
||||||
|
iat++;
|
||||||
|
}
|
||||||
|
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( !warn )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -87,6 +87,7 @@ pfn_t alloc_page() __attribute__ ((deprecated));
|
|||||||
|
|
||||||
|
|
||||||
md_t* __fastcall md_alloc(size_t size, u32_t flags) ;
|
md_t* __fastcall md_alloc(size_t size, u32_t flags) ;
|
||||||
|
void __fastcall md_free(md_t *md);
|
||||||
|
|
||||||
void* __fastcall __export mem_alloc(size_t size, u32_t flags) asm ("MemAlloc");
|
void* __fastcall __export mem_alloc(size_t size, u32_t flags) asm ("MemAlloc");
|
||||||
void __fastcall __export mem_free(void *mem) asm ("MemFree");
|
void __fastcall __export mem_free(void *mem) asm ("MemFree");
|
||||||
|
202
kernel/branches/kolibri_pe/include/pe.h
Normal file
202
kernel/branches/kolibri_pe/include/pe.h
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned int DWORD;
|
||||||
|
typedef unsigned int LONG;
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
|
||||||
|
#define IMAGE_DOS_SIGNATURE 0x5A4D
|
||||||
|
#define IMAGE_NT_SIGNATURE 0x00004550
|
||||||
|
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||||
|
|
||||||
|
#pragma pack(push,2)
|
||||||
|
typedef struct _IMAGE_DOS_HEADER
|
||||||
|
{
|
||||||
|
WORD e_magic;
|
||||||
|
WORD e_cblp;
|
||||||
|
WORD e_cp;
|
||||||
|
WORD e_crlc;
|
||||||
|
WORD e_cparhdr;
|
||||||
|
WORD e_minalloc;
|
||||||
|
WORD e_maxalloc;
|
||||||
|
WORD e_ss;
|
||||||
|
WORD e_sp;
|
||||||
|
WORD e_csum;
|
||||||
|
WORD e_ip;
|
||||||
|
WORD e_cs;
|
||||||
|
WORD e_lfarlc;
|
||||||
|
WORD e_ovno;
|
||||||
|
WORD e_res[4];
|
||||||
|
WORD e_oemid;
|
||||||
|
WORD e_oeminfo;
|
||||||
|
WORD e_res2[10];
|
||||||
|
LONG e_lfanew;
|
||||||
|
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(push,4)
|
||||||
|
typedef struct _IMAGE_FILE_HEADER
|
||||||
|
{
|
||||||
|
WORD Machine;
|
||||||
|
WORD NumberOfSections;
|
||||||
|
DWORD TimeDateStamp;
|
||||||
|
DWORD PointerToSymbolTable;
|
||||||
|
DWORD NumberOfSymbols;
|
||||||
|
WORD SizeOfOptionalHeader;
|
||||||
|
WORD Characteristics;
|
||||||
|
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||||
|
DWORD VirtualAddress;
|
||||||
|
DWORD Size;
|
||||||
|
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
|
||||||
|
|
||||||
|
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||||
|
|
||||||
|
typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||||
|
WORD Magic;
|
||||||
|
BYTE MajorLinkerVersion;
|
||||||
|
BYTE MinorLinkerVersion;
|
||||||
|
DWORD SizeOfCode;
|
||||||
|
DWORD SizeOfInitializedData;
|
||||||
|
DWORD SizeOfUninitializedData;
|
||||||
|
DWORD AddressOfEntryPoint;
|
||||||
|
DWORD BaseOfCode;
|
||||||
|
DWORD BaseOfData;
|
||||||
|
DWORD ImageBase;
|
||||||
|
DWORD SectionAlignment;
|
||||||
|
DWORD FileAlignment;
|
||||||
|
WORD MajorOperatingSystemVersion;
|
||||||
|
WORD MinorOperatingSystemVersion;
|
||||||
|
WORD MajorImageVersion;
|
||||||
|
WORD MinorImageVersion;
|
||||||
|
WORD MajorSubsystemVersion;
|
||||||
|
WORD MinorSubsystemVersion;
|
||||||
|
DWORD Win32VersionValue;
|
||||||
|
DWORD SizeOfImage;
|
||||||
|
DWORD SizeOfHeaders;
|
||||||
|
DWORD CheckSum;
|
||||||
|
WORD Subsystem;
|
||||||
|
WORD DllCharacteristics;
|
||||||
|
DWORD SizeOfStackReserve;
|
||||||
|
DWORD SizeOfStackCommit;
|
||||||
|
DWORD SizeOfHeapReserve;
|
||||||
|
DWORD SizeOfHeapCommit;
|
||||||
|
DWORD LoaderFlags;
|
||||||
|
DWORD NumberOfRvaAndSizes;
|
||||||
|
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||||
|
} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(push,4)
|
||||||
|
typedef struct _IMAGE_NT_HEADERS
|
||||||
|
{
|
||||||
|
DWORD Signature;
|
||||||
|
IMAGE_FILE_HEADER FileHeader;
|
||||||
|
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||||
|
} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
|
||||||
|
|
||||||
|
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||||
|
|
||||||
|
typedef struct _IMAGE_SECTION_HEADER
|
||||||
|
{
|
||||||
|
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||||
|
union
|
||||||
|
{
|
||||||
|
DWORD PhysicalAddress;
|
||||||
|
DWORD VirtualSize;
|
||||||
|
} Misc;
|
||||||
|
DWORD VirtualAddress;
|
||||||
|
DWORD SizeOfRawData;
|
||||||
|
DWORD PointerToRawData;
|
||||||
|
DWORD PointerToRelocations;
|
||||||
|
DWORD PointerToLinenumbers;
|
||||||
|
WORD NumberOfRelocations;
|
||||||
|
WORD NumberOfLinenumbers;
|
||||||
|
DWORD Characteristics;
|
||||||
|
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push,4)
|
||||||
|
typedef struct _IMAGE_BASE_RELOCATION {
|
||||||
|
DWORD VirtualAddress;
|
||||||
|
DWORD SizeOfBlock;
|
||||||
|
} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef struct _IMAGE_IMPORT_DESCRIPTOR
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
DWORD Characteristics;
|
||||||
|
DWORD OriginalFirstThunk;
|
||||||
|
};
|
||||||
|
DWORD TimeDateStamp;
|
||||||
|
DWORD ForwarderChain;
|
||||||
|
DWORD Name;
|
||||||
|
DWORD FirstThunk;
|
||||||
|
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_THUNK_DATA32
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
DWORD ForwarderString;
|
||||||
|
DWORD Function;
|
||||||
|
DWORD Ordinal;
|
||||||
|
DWORD AddressOfData;
|
||||||
|
} u1;
|
||||||
|
} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_IMPORT_BY_NAME
|
||||||
|
{
|
||||||
|
WORD Hint;
|
||||||
|
BYTE Name[1];
|
||||||
|
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
|
||||||
|
|
||||||
|
#define IMAGE_ORDINAL_FLAG 0x80000000
|
||||||
|
|
||||||
|
typedef struct _IMAGE_EXPORT_DIRECTORY {
|
||||||
|
DWORD Characteristics;
|
||||||
|
DWORD TimeDateStamp;
|
||||||
|
WORD MajorVersion;
|
||||||
|
WORD MinorVersion;
|
||||||
|
DWORD Name;
|
||||||
|
DWORD Base;
|
||||||
|
DWORD NumberOfFunctions;
|
||||||
|
DWORD NumberOfNames;
|
||||||
|
DWORD AddressOfFunctions;
|
||||||
|
DWORD AddressOfNames;
|
||||||
|
DWORD AddressOfNameOrdinals;
|
||||||
|
} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
link_t link;
|
||||||
|
|
||||||
|
addr_t img_base;
|
||||||
|
size_t img_size;
|
||||||
|
char *img_name;
|
||||||
|
md_t *img_md;
|
||||||
|
|
||||||
|
PIMAGE_NT_HEADERS32 img_hdr;
|
||||||
|
PIMAGE_SECTION_HEADER img_sec;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY img_exp;
|
||||||
|
u32_t img_map[8]; /* mapped treads */
|
||||||
|
}dll_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addr_t)(addValue) )
|
||||||
|
|
||||||
|
|
||||||
|
dll_t * find_dll(const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
md_t* __fastcall load_image(const char *path);
|
||||||
|
|
||||||
|
void __export create_image(addr_t img_base, addr_t image) asm ("CreateImage");
|
||||||
|
|
||||||
|
|
@ -179,11 +179,12 @@ extrn _poweroff
|
|||||||
|
|
||||||
extrn _init
|
extrn _init
|
||||||
extrn _init_mm
|
extrn _init_mm
|
||||||
|
extrn @init_heap@8
|
||||||
|
extrn _init_core_dll
|
||||||
|
|
||||||
extrn @core_alloc@4
|
extrn @core_alloc@4
|
||||||
extrn @core_free@4
|
extrn @core_free@4
|
||||||
|
|
||||||
extrn @init_heap@8
|
|
||||||
extrn @find_large_md@4
|
extrn @find_large_md@4
|
||||||
|
|
||||||
extrn _MemAlloc
|
extrn _MemAlloc
|
||||||
@ -402,6 +403,8 @@ __core_restart:
|
|||||||
mov edx, 0x40000000
|
mov edx, 0x40000000
|
||||||
call @init_heap@8
|
call @init_heap@8
|
||||||
|
|
||||||
|
call _init_core_dll
|
||||||
|
|
||||||
mov esi, _16bit_start
|
mov esi, _16bit_start
|
||||||
mov ecx, _16bit_end
|
mov ecx, _16bit_end
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# This script does for linux the same as build.bat for DOS,
|
|
||||||
# it compiles the KoOS kernel, hopefully ;-)
|
|
||||||
|
|
||||||
CLANG=$1;
|
|
||||||
|
|
||||||
usage()
|
|
||||||
{
|
|
||||||
echo "Usage: make.sh [en|ru|ge|et]"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
compile()
|
|
||||||
{
|
|
||||||
fasm -m 65536 kernel.asm bin/kernel.mnt
|
|
||||||
rm -f lang.inc
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if [ ! $CLANG ] ; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
for i in "en" "ru" "ge" "et"; do
|
|
||||||
if [ $i == $CLANG ] ; then
|
|
||||||
echo "lang fix $i" > lang.inc
|
|
||||||
compile
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
usage
|
|
||||||
|
|
||||||
|
|
@ -30,6 +30,7 @@ PE_SRC:= \
|
|||||||
mm.c \
|
mm.c \
|
||||||
slab.c \
|
slab.c \
|
||||||
heap.c \
|
heap.c \
|
||||||
|
pe.c \
|
||||||
dll.c \
|
dll.c \
|
||||||
spinlock.c \
|
spinlock.c \
|
||||||
boot/boot.asm \
|
boot/boot.asm \
|
||||||
|
Loading…
Reference in New Issue
Block a user