Subversion Repositories Kolibri OS

Rev

Rev 892 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <types.h>
  3. #include <core.h>
  4. #include <spinlock.h>
  5. #include <link.h>
  6. #include <mm.h>
  7. #include <slab.h>
  8.  
  9. typedef unsigned short WORD;
  10. typedef unsigned int DWORD;
  11. typedef unsigned int LONG;
  12. typedef unsigned char BYTE;
  13.  
  14. #define IMAGE_DOS_SIGNATURE  0x5A4D
  15. #define IMAGE_NT_SIGNATURE   0x00004550
  16. #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
  17.  
  18. #pragma pack(push,2)
  19. typedef struct _IMAGE_DOS_HEADER
  20. {
  21.     WORD    e_magic;
  22.     WORD    e_cblp;
  23.     WORD    e_cp;
  24.     WORD    e_crlc;
  25.     WORD    e_cparhdr;
  26.     WORD    e_minalloc;
  27.     WORD    e_maxalloc;
  28.     WORD    e_ss;
  29.     WORD    e_sp;
  30.     WORD    e_csum;
  31.     WORD    e_ip;
  32.     WORD    e_cs;
  33.     WORD    e_lfarlc;
  34.     WORD    e_ovno;
  35.     WORD    e_res[4];
  36.     WORD    e_oemid;
  37.     WORD    e_oeminfo;
  38.     WORD    e_res2[10];
  39.     LONG    e_lfanew;
  40. } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
  41. #pragma pack(pop)
  42.  
  43.  
  44. #pragma pack(push,4)
  45. typedef struct _IMAGE_FILE_HEADER
  46. {
  47.     WORD    Machine;
  48.     WORD    NumberOfSections;
  49.     DWORD   TimeDateStamp;
  50.     DWORD   PointerToSymbolTable;
  51.     DWORD   NumberOfSymbols;
  52.     WORD    SizeOfOptionalHeader;
  53.     WORD    Characteristics;
  54. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
  55.  
  56. typedef struct _IMAGE_DATA_DIRECTORY {
  57.     DWORD   VirtualAddress;
  58.     DWORD   Size;
  59. } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
  60.  
  61. #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
  62.  
  63. typedef struct _IMAGE_OPTIONAL_HEADER {
  64.     WORD    Magic;
  65.     BYTE    MajorLinkerVersion;
  66.     BYTE    MinorLinkerVersion;
  67.     DWORD   SizeOfCode;
  68.     DWORD   SizeOfInitializedData;
  69.     DWORD   SizeOfUninitializedData;
  70.     DWORD   AddressOfEntryPoint;
  71.     DWORD   BaseOfCode;
  72.     DWORD   BaseOfData;
  73.     DWORD   ImageBase;
  74.     DWORD   SectionAlignment;
  75.     DWORD   FileAlignment;
  76.     WORD    MajorOperatingSystemVersion;
  77.     WORD    MinorOperatingSystemVersion;
  78.     WORD    MajorImageVersion;
  79.     WORD    MinorImageVersion;
  80.     WORD    MajorSubsystemVersion;
  81.     WORD    MinorSubsystemVersion;
  82.     DWORD   Win32VersionValue;
  83.     DWORD   SizeOfImage;
  84.     DWORD   SizeOfHeaders;
  85.     DWORD   CheckSum;
  86.     WORD    Subsystem;
  87.     WORD    DllCharacteristics;
  88.     DWORD   SizeOfStackReserve;
  89.     DWORD   SizeOfStackCommit;
  90.     DWORD   SizeOfHeapReserve;
  91.     DWORD   SizeOfHeapCommit;
  92.     DWORD   LoaderFlags;
  93.     DWORD   NumberOfRvaAndSizes;
  94.         IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  95. } IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
  96.  
  97. #pragma pack(pop)
  98.  
  99.  
  100. #pragma pack(push,4)
  101. typedef struct _IMAGE_NT_HEADERS
  102. {
  103.     DWORD Signature;
  104.         IMAGE_FILE_HEADER FileHeader;
  105.         IMAGE_OPTIONAL_HEADER OptionalHeader;
  106. } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
  107.  
  108. #define IMAGE_SIZEOF_SHORT_NAME    8
  109.  
  110. typedef struct _IMAGE_SECTION_HEADER
  111. {
  112.         BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
  113.     union
  114.     {
  115.         DWORD PhysicalAddress;
  116.                 DWORD VirtualSize;
  117.         } Misc;
  118.     DWORD   VirtualAddress;
  119.     DWORD   SizeOfRawData;
  120.     DWORD   PointerToRawData;
  121.     DWORD   PointerToRelocations;
  122.     DWORD   PointerToLinenumbers;
  123.     WORD    NumberOfRelocations;
  124.     WORD    NumberOfLinenumbers;
  125.     DWORD   Characteristics;
  126. } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
  127. #pragma pack(pop)
  128.  
  129. #pragma pack(push,4)
  130. typedef struct _IMAGE_BASE_RELOCATION {
  131.         DWORD VirtualAddress;
  132.         DWORD SizeOfBlock;
  133. } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
  134. #pragma pack(pop)
  135.  
  136. typedef struct _IMAGE_IMPORT_DESCRIPTOR
  137. {
  138.     union
  139.     {
  140.                 DWORD Characteristics;
  141.                 DWORD OriginalFirstThunk;
  142.     };
  143.     DWORD   TimeDateStamp;
  144.     DWORD   ForwarderChain;
  145.     DWORD   Name;
  146.     DWORD   FirstThunk;
  147. } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
  148.  
  149. typedef struct _IMAGE_THUNK_DATA32
  150. {
  151.     union
  152.     {
  153.                 DWORD ForwarderString;
  154.                 DWORD Function;
  155.                 DWORD Ordinal;
  156.                 DWORD AddressOfData;
  157.         } u1;
  158. } IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
  159.  
  160. typedef struct _IMAGE_IMPORT_BY_NAME
  161. {
  162.         WORD Hint;
  163.         BYTE Name[1];
  164. } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
  165.  
  166. #define IMAGE_ORDINAL_FLAG 0x80000000
  167.  
  168. typedef struct _IMAGE_EXPORT_DIRECTORY {
  169.         DWORD Characteristics;
  170.         DWORD TimeDateStamp;
  171.         WORD MajorVersion;
  172.         WORD MinorVersion;
  173.         DWORD Name;
  174.         DWORD Base;
  175.         DWORD NumberOfFunctions;
  176.         DWORD NumberOfNames;
  177.         DWORD AddressOfFunctions;
  178.         DWORD AddressOfNames;
  179.         DWORD AddressOfNameOrdinals;
  180. } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
  181.  
  182. //extern  IMAGE_EXPORT_DIRECTORY kernel_exports;
  183.  
  184. #define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addValue) )
  185.  
  186. typedef struct
  187. {
  188.     addr_t  base;
  189.     addr_t  frame;
  190.     md_t    *md;
  191.  
  192.     IMAGE_OPTIONAL_HEADER  *opthdr;
  193.  
  194. }dll_t;
  195.  
  196. static inline bool IsPowerOf2(u32_t val)
  197. {
  198.     if(val == 0)
  199.         return false;
  200.     return (val & (val - 1)) == 0;
  201. }
  202.  
  203.  
  204. static inline void sec_copy(void *dst, const void *src, size_t len)
  205. {
  206.     u32_t tmp;
  207.     __asm__ __volatile__ (
  208.     "shrl $2, %%ecx         \n\t"
  209.     "rep movsl"
  210.     :"=c"(tmp),"=S"(tmp),"=D"(tmp)
  211.     :"c"(len),"S"(src),"D"(dst)
  212.     :"cc");
  213. };
  214.  
  215. static inline void sec_clear(void *dst, size_t len)
  216. {
  217.     u32_t tmp;
  218.     __asm__ __volatile__ (
  219.     "xorl %%eax, %%eax      \n\t"
  220.     "rep stosb"
  221.     :"=c"(tmp),"=D"(tmp)
  222.     :"c"(len),"D"(dst)
  223.     :"eax","cc");
  224. };
  225.  
  226. int __stdcall strncmp(const char *s1, const char *s2, size_t n);
  227.  
  228.  
  229. void __export create_image(void *img_base, void *image) asm ("CreateImage");
  230.  
  231. md_t* __fastcall load_image(const char *path);
  232.  
  233.  
  234. void* __fastcall load_pe(const char *path)
  235. {
  236.     md_t  *md;
  237.  
  238.     md = load_image(path);
  239.  
  240.     if( md )
  241.         return (void*)md->base;
  242.  
  243.     return NULL;
  244. };
  245.  
  246. typedef struct
  247. {
  248.   char         srv_name[16];  //        ASCIIZ string
  249.   u32_t        magic;         // +0x10  'SRV '
  250.   size_t       size;          // +0x14  size of structure SRV
  251.   void        *fd;            // +0x18  next SRV descriptor
  252.   void        *bk;            // +0x1C  prev SRV descriptor
  253.   addr_t       base;          // +0x20  service base address
  254.   addr_t       entry;         // +0x24  service START function
  255.   void        *srv_proc;      // +0x28  main service handler
  256. }srv_t;
  257.  
  258. typedef srv_t* __stdcall  drv_entry_t(int);
  259.  
  260. srv_t* __fastcall load_pe_driver(const char *path)
  261. {
  262.     PIMAGE_DOS_HEADER     dos;
  263.     PIMAGE_NT_HEADERS32   nt;
  264.  
  265.     drv_entry_t   *drv_entry;
  266.     md_t          *md;
  267.     srv_t         *srv;
  268.  
  269.     md = load_image(path);
  270.  
  271.     if( ! md )
  272.         return 0;
  273.  
  274.     dos = (PIMAGE_DOS_HEADER)md->base;
  275.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  276.  
  277.     drv_entry = MakePtr(drv_entry_t*, md->base,
  278.                         nt->OptionalHeader.AddressOfEntryPoint);
  279.  
  280.     srv = drv_entry(1);
  281.  
  282.     if(srv != NULL)
  283.        srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base;
  284.  
  285.     return srv;
  286. }
  287.  
  288. md_t* __fastcall load_image(const char *path)
  289. {
  290.     PIMAGE_DOS_HEADER     dos;
  291.     PIMAGE_NT_HEADERS32   nt;
  292.  
  293.     md_t    *img_md;
  294.  
  295.     size_t   img_size;
  296.     void    *img_base;
  297.     count_t  img_pages;
  298.  
  299.     size_t   raw_size = 0;
  300.     void    *raw;
  301.  
  302. //    void    *image;
  303.  
  304.     DBG("load file %s\n", path);
  305.  
  306.     raw = load_file(path, &raw_size);
  307.  
  308.     DBG("raw = %x\n\n", raw);
  309.  
  310.     dos = (PIMAGE_DOS_HEADER)raw;
  311.  
  312.     if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) )
  313.         return NULL;
  314.  
  315.     if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0)
  316.         return NULL;
  317.  
  318.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  319.  
  320.     if( (addr_t)nt < (addr_t)raw)
  321.         return NULL;
  322.  
  323.     if(nt->Signature != IMAGE_NT_SIGNATURE)
  324.         return NULL;
  325.  
  326.     if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
  327.         return NULL;
  328.  
  329.     if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE)
  330.         {
  331.         if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
  332.             return NULL;
  333.         }
  334.     else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
  335.         return NULL;
  336.  
  337.     if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) ||
  338.        !IsPowerOf2(nt->OptionalHeader.FileAlignment))
  339.         return NULL;
  340.  
  341.     if(nt->FileHeader.NumberOfSections > 96)
  342.         return NULL;
  343.  
  344.     img_size  =  nt->OptionalHeader.SizeOfImage;
  345. //    img_pages = img_size / PAGE_SIZE;
  346.  
  347.     img_md  = md_alloc(img_size, PG_SW);
  348.  
  349.  
  350.     if( !img_md)
  351.     {
  352.         mem_free(raw);
  353.         return NULL;
  354.     };
  355.  
  356.     img_base = (void*)img_md->base;
  357.  
  358.     create_image(img_base, raw);
  359.  
  360.     mem_free(raw);
  361.  
  362. //    dos = (PIMAGE_DOS_HEADER)img_base;
  363. //    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  364.  
  365.     return img_md;
  366. };
  367.  
  368.  
  369. /*
  370. addr_t get_proc_addr(addr_t module, char *name)
  371. {
  372.     PIMAGE_DOS_HEADER  expdos;
  373.     PIMAGE_NT_HEADERS32  expnt;
  374.     PIMAGE_EXPORT_DIRECTORY exp;
  375.     u32_t *functions;
  376.     char **funcname;
  377.     int ind;
  378.  
  379.     expdos = (PIMAGE_DOS_HEADER)module;
  380.     expnt =  MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew);
  381.  
  382.     exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,module,
  383.                   expnt->OptionalHeader.DataDirectory[0].VirtualAddress);
  384.  
  385.     functions = MakePtr(DWORD*,exp->AddressOfFunctions,module);
  386.     funcname = MakePtr(char**,exp->AddressOfNames,module);
  387.  
  388.     for(ind=0; *funcname;funcname++,ind++)
  389.     {
  390.         if(!strcmp(name,MakePtr(char*,*funcname,module)))
  391.             return functions[ind] + module;
  392.     };
  393.     return -1;
  394. };
  395. */
  396.  
  397.  
  398. void create_image(void *img_base, void *image)
  399. {
  400.     PIMAGE_DOS_HEADER     dos;
  401.     PIMAGE_NT_HEADERS32   nt;
  402.     PIMAGE_SECTION_HEADER img_sec;
  403.  
  404.     u32_t  sec_align;
  405.     int    i;
  406.  
  407.  
  408. /* assumed that image is valid */
  409.  
  410.     dos = (PIMAGE_DOS_HEADER)image;
  411.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  412.  
  413.     sec_copy(img_base,image,nt->OptionalHeader.SizeOfHeaders);
  414.  
  415.     img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32));
  416.  
  417.     sec_align = nt->OptionalHeader.SectionAlignment;
  418.  
  419.     for(i=0; i< nt->FileHeader.NumberOfSections; i++)
  420.     {
  421.         char *src_ptr;
  422.         char *dest_ptr;
  423.         size_t sec_size;
  424.  
  425.         src_ptr = MakePtr(char*, image, img_sec->PointerToRawData);
  426.         dest_ptr = MakePtr(char*,img_base, img_sec->VirtualAddress);
  427.  
  428.         if(img_sec->SizeOfRawData)
  429.             sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
  430.  
  431.         sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align;
  432.  
  433.         if(sec_size > img_sec->SizeOfRawData)
  434.             sec_clear(dest_ptr + img_sec->SizeOfRawData,
  435.                       sec_size - img_sec->SizeOfRawData);
  436.         img_sec++;
  437.     }
  438.  
  439.     if(nt->OptionalHeader.DataDirectory[5].Size)
  440.     {
  441.         PIMAGE_BASE_RELOCATION reloc;
  442.  
  443. /* FIXME addr_t */
  444.  
  445.         u32_t delta = (u32_t)img_base - nt->OptionalHeader.ImageBase;
  446.  
  447.         reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base,
  448.                         nt->OptionalHeader.DataDirectory[5].VirtualAddress);
  449.  
  450.         while ( reloc->SizeOfBlock != 0 )
  451.         {
  452.             u32_t  cnt;
  453.             u16_t *entry;
  454.             u16_t  reltype;
  455.             u32_t  offs;
  456.  
  457.             cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(u16_t);
  458.             entry = MakePtr( u16_t*, reloc, sizeof(*reloc) );
  459.  
  460.             for ( i=0; i < cnt; i++ )
  461.             {
  462.                 u16_t *p16;
  463.                 u32_t *p32;
  464.  
  465.                 reltype = (*entry & 0xF000) >> 12;
  466.                 offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
  467.                 switch(reltype)
  468.                 {
  469.                     case 1:
  470.                         p16 = MakePtr(u16_t*, img_base, offs);
  471.                         *p16+= (u16_t)(delta>>16);
  472.                         break;
  473.                     case 2:
  474.                         p16 = MakePtr(u16_t*, img_base, offs);
  475.                         *p16+= (u16_t)delta;
  476.                         break;
  477.                     case 3:
  478.                         p32 = MakePtr(u32_t*, img_base, offs);
  479.                         *p32+= delta;
  480.                 }
  481.                 entry++;
  482.             }
  483.             reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
  484.         }
  485.     };
  486.  
  487.     if(nt->OptionalHeader.DataDirectory[1].Size)
  488.     {
  489.         PIMAGE_IMPORT_DESCRIPTOR imp;
  490.  
  491.         int warn = 0;
  492.  
  493.         imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
  494.                       nt->OptionalHeader.DataDirectory[1].VirtualAddress);
  495.  
  496.  
  497.  
  498.         while ( 1 )
  499.         {
  500.             PIMAGE_THUNK_DATA32     thunk;
  501.  
  502.             PIMAGE_DOS_HEADER       expdos;
  503.             PIMAGE_NT_HEADERS32     expnt;
  504.             PIMAGE_EXPORT_DIRECTORY exp;
  505.  
  506.             u32_t   *iat;
  507.             char    *libname;
  508.             addr_t  *functions;
  509.             u16_t   *ordinals;
  510.             char   **funcname;
  511.  
  512.  
  513.             if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
  514.                 break;
  515.  
  516.             libname=MakePtr(char*,imp->Name, img_base);
  517.  
  518.             DBG("import from %s\n",libname);
  519.  
  520.             expdos = (PIMAGE_DOS_HEADER)IMAGE_BASE;
  521.             expnt =  MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew);
  522.  
  523.             exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
  524.                     expnt->OptionalHeader.DataDirectory[0].VirtualAddress);
  525.  
  526.             functions = MakePtr(DWORD*,exp->AddressOfFunctions,LOAD_BASE);
  527.             ordinals = MakePtr(WORD*,  exp->AddressOfNameOrdinals,LOAD_BASE);
  528.             funcname = MakePtr(char**, exp->AddressOfNames,LOAD_BASE);
  529.  
  530.             thunk = MakePtr(PIMAGE_THUNK_DATA32,
  531.                             imp->Characteristics, img_base);
  532.             iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
  533.  
  534.             while ( 1 ) // Loop forever (or until we break out)
  535.             {
  536.                 PIMAGE_IMPORT_BY_NAME ord;
  537.                 addr_t addr;
  538.  
  539.                 if ( thunk->u1.AddressOfData == 0 )
  540.                     break;
  541.  
  542.                 if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
  543.                 {
  544.         //  printf("  %4u\n", thunk->u1.Ordinal & 0xFFFF);
  545.                     break;
  546.                 }
  547.                 else
  548.                 {
  549.                     ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
  550.                                   thunk->u1.AddressOfData, img_base);
  551.                     *iat=0;
  552.  
  553.                     DBG("import %s", ord->Name);
  554.  
  555.                     if(strncmp(ord->Name,
  556.                        MakePtr(char*,funcname[ord->Hint],LOAD_BASE),32))
  557.                     {
  558.                         int ind;
  559.                         char **names=funcname;
  560.  
  561.                         for(names = funcname,ind = 0;
  562.                             ind < exp->NumberOfNames; names++,ind++)
  563.                         {
  564.                             if(!strncmp(ord->Name,MakePtr(char*,*names,LOAD_BASE),32))
  565.                             {
  566.                                 DBG(" \tat %x\n", functions[ind] + LOAD_BASE);
  567.                                 *iat = functions[ind] + LOAD_BASE;
  568.                                 break;
  569.                             };
  570.                         };
  571.                         if(ind == exp->NumberOfNames)
  572.                         {
  573.                             DBG(" unresolved import %s\n",ord->Name);
  574.                             warn=1;
  575.                         };
  576.                     }
  577.                     else
  578.                     {
  579.                         DBG(" \tat %x\n", functions[ord->Hint] + LOAD_BASE);
  580.                         *iat = functions[ord->Hint] + LOAD_BASE;
  581.                     };
  582.                 };
  583.                 thunk++;            // Advance to next thunk
  584.                 iat++;
  585.             }
  586.             imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
  587.         };
  588.     };
  589.  
  590.     DBG("\ncreate pe base %x, size %x, %d sections\n\n",img_base,
  591.          nt->OptionalHeader.SizeOfImage, nt->FileHeader.NumberOfSections);
  592. };
  593.  
  594.  
  595.  
  596.  
  597.  
  598. /*
  599.  
  600. u32 map_PE(u32 base, void *image)
  601. {
  602.   PIMAGE_DOS_HEADER dos;
  603.   PIMAGE_NT_HEADERS32 nt;
  604.   PIMAGE_SECTION_HEADER sec;
  605.  
  606.   int i;
  607.   int pages;
  608.  
  609.   dos = (PIMAGE_DOS_HEADER)image;
  610.   nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  611.  
  612.  
  613.     img_size  =  nt->OptionalHeader.SizeOfImage;
  614.     img_pages = img_size / PAGE_SIZE;
  615.  
  616.     img_md  = md_alloc(img_size, PG_SW);
  617.  
  618.     if( !img_md)
  619.         return NULL;
  620.  
  621.  
  622.  
  623.   scopy(base,(u32)image,nt->OptionalHeader.SizeOfHeaders);
  624.  
  625.   sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32));
  626.  
  627.  
  628.   if(nt->OptionalHeader.DataDirectory[1].Size)
  629.   {
  630.     PIMAGE_IMPORT_DESCRIPTOR imp;
  631.  
  632.     imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR,base,
  633.                   nt->OptionalHeader.DataDirectory[1].VirtualAddress);
  634.     while ( 1 )
  635.     {
  636.       PIMAGE_THUNK_DATA32 thunk;
  637.       u32 *iat;
  638.       char *libname;
  639.  
  640.       if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
  641.         break;
  642.  
  643.  
  644.       thunk = MakePtr(PIMAGE_THUNK_DATA32,
  645.                       imp->Characteristics, base);
  646.       iat= MakePtr(DWORD*,imp->FirstThunk, base);
  647.  
  648.       while ( 1 ) // Loop forever (or until we break out)
  649.       {
  650.         PIMAGE_IMPORT_BY_NAME ord;
  651.  
  652.         u32 addr;
  653.  
  654.         if ( thunk->u1.AddressOfData == 0 )
  655.           break;
  656.  
  657.         if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
  658.         {
  659.         //  printf("  %4u\n", thunk->u1.Ordinal & 0xFFFF);
  660.             break;
  661.         }
  662.         else
  663.         {
  664.           PKERNEL_EXPORT exp;
  665.           exp = kernel_export;
  666.  
  667.           ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
  668.                         thunk->u1.AddressOfData,base);
  669.           *iat=-1;
  670.  
  671.           do
  672.           {
  673.             if(!strncmp(ord->Name,exp->name,16))
  674.             {
  675.               *iat = exp->address;
  676.               break;
  677.             }
  678.             exp++;
  679.           } while(exp->name != 0);
  680.         };
  681.         thunk++;            // Advance to next thunk
  682.         iat++;
  683.       }
  684.       imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
  685.     }
  686.   };
  687.  
  688. */
  689.