Subversion Repositories Kolibri OS

Rev

Rev 996 | 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. #include <pe.h>
  9.  
  10. #pragma pack(push,4)
  11. typedef struct
  12. {
  13.   char     app_name[16];
  14.   addr_t   fpu_state;                       /*      +16       */
  15.   count_t  ev_count;                        /*      +20       */
  16.   addr_t   fpu_handler;                     /*      +24       */
  17.   addr_t   sse_handler;                     /*      +28       */
  18.   addr_t   pl0_stack;                       /*      +32       */
  19.  
  20.   addr_t   heap_base;                       /*      +36       */
  21.   addr_t   heap_top;                        /*      +40       */
  22.   addr_t   cursor;                          /*      +44       */
  23.   addr_t   fd_ev;                           /*      +48       */
  24.   addr_t   bk_ev;                           /*      +52       */
  25.   addr_t   fd_obj;                          /*      +56       */
  26.   addr_t   bk_obj;                          /*      +60       */
  27.   addr_t   saved_esp;                       /*      +64       */
  28.   addr_t   io_map[2];                       /*      +68       */
  29.  
  30.   u32_t    dbg_state;                       /*      +76       */
  31.   char    *cur_dir;                         /*      +80       */
  32.   count_t  wait_timeout;                    /*      +84       */
  33.   addr_t   saved_esp0;                      /*      +88       */
  34.  
  35.   link_t   dll_list;                        /*      +92       */
  36.  
  37.   u32_t    reserved0[7];                    /*      +100   db 28 dup(?)  */
  38.  
  39.   addr_t   wnd_shape;                       /*      +128      */
  40.   u32_t    wnd_shape_scale;                 /*      +132      */
  41.   u32_t    reserved1;                       /*      +136      */
  42.   size_t   mem_size;                        /*      +140      */
  43. }appdata_t;
  44. #pragma pack(pop)
  45.  
  46.  
  47. extern appdata_t *current_slot;
  48.  
  49. bool link_pe(addr_t img_base);
  50.  
  51. int __stdcall strncmp(const char *s1, const char *s2, size_t n);
  52.  
  53. extern int __stdcall mnt_exec(void *raw, size_t raw_size, char *path,
  54.               char *cmdline, u32_t flags) asm ("mnt_exec");
  55.  
  56. dll_t core_dll;
  57.  
  58. slab_cache_t *dll_slab;
  59.  
  60. static char* strupr(char *str )
  61. {
  62.     char *p;
  63.     unsigned char c;
  64.  
  65.     p = str;
  66.     while( (c = *p) )
  67.     {
  68.         if( c >= 'a' && c <= 'z' )
  69.             *p = c - 'a' + 'A';
  70.         ++p;
  71.     }
  72.  
  73.     return( str );
  74. }
  75.  
  76. void * memcpy(void * _dest, const void *_src, size_t _n)
  77. {
  78. int d0, d1, d2;
  79.  __asm__ __volatile__(
  80.         "rep ; movsl\n\t"
  81.         "testb $2,%b4\n\t"
  82.         "je 1f\n\t"
  83.         "movsw\n"
  84.         "1:\ttestb $1,%b4\n\t"
  85.         "je 2f\n\t"
  86.         "movsb\n"
  87.         "2:"
  88.         : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  89.         :"0" (_n/4), "q" (_n),"1" ((long)_dest),"2" ((long)_src)
  90.         : "memory");
  91.  return (_dest);
  92. }
  93.  
  94. size_t strlen(const char *str)
  95. {
  96. int d0;
  97. register int __res;
  98. __asm__ __volatile__(
  99.         "repne\n\t"
  100.         "scasb\n\t"
  101.         "notl %0\n\t"
  102.         "decl %0"
  103.         :"=c" (__res), "=&D" (d0) :"1" (str),"a" (0), "0" (0xffffffff));
  104. return __res;
  105. }
  106.  
  107. void init_core_dll()
  108. {
  109.     PIMAGE_DOS_HEADER        dos;
  110.     PIMAGE_NT_HEADERS32      nt;
  111.     PIMAGE_EXPORT_DIRECTORY  exp;
  112.  
  113.     dos =  (PIMAGE_DOS_HEADER)LOAD_BASE;
  114.     nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  115.     exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
  116.                    nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  117.  
  118.     list_initialize(&core_dll.link);
  119.  
  120.     core_dll.img_base = LOAD_BASE;
  121.     core_dll.img_size = nt->OptionalHeader.SizeOfImage;
  122.     core_dll.img_md   = NULL;
  123.  
  124.     core_dll.img_hdr  = nt;
  125.     core_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
  126.     core_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
  127.                         nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  128.     core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name));
  129.  
  130.     dll_slab = slab_cache_create(sizeof(dll_t), 16,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
  131.  
  132.     DBG("%s base %x size %x sections %d exports %x\n",
  133.         core_dll.img_name, core_dll.img_base,
  134.         core_dll.img_size, nt->FileHeader.NumberOfSections,
  135.         core_dll.img_exp );
  136. };
  137.  
  138.  
  139. dll_t * find_dll(link_t *list, const char *name)
  140. {
  141.     dll_t* dll = (dll_t*)list;
  142.  
  143.     do
  144.     {
  145.         if( !strncmp(name,dll->img_name,16))
  146.             return dll;
  147.  
  148.         dll = (dll_t*)dll->link.next;
  149.  
  150.     }while(&dll->link !=  list);
  151.  
  152.     return NULL;
  153. };
  154.  
  155.  
  156. typedef struct
  157. {
  158.   char         srv_name[16];  //        ASCIIZ string
  159.   u32_t        magic;         // +0x10  'SRV '
  160.   size_t       size;          // +0x14  size of structure SRV
  161.   void        *fd;            // +0x18  next SRV descriptor
  162.   void        *bk;            // +0x1C  prev SRV descriptor
  163.   addr_t       base;          // +0x20  service base address
  164.   addr_t       entry;         // +0x24  service START function
  165.   void        *srv_proc;      // +0x28  main service handler
  166. }srv_t;
  167.  
  168. typedef srv_t* __stdcall  drv_entry_t(int);
  169.  
  170. srv_t* __fastcall load_pe_driver(const char *path)
  171. {
  172.     PIMAGE_DOS_HEADER     dos;
  173.     PIMAGE_NT_HEADERS32   nt;
  174.  
  175.     drv_entry_t   *drv_entry;
  176.     addr_t        *img_base ;
  177.     srv_t         *srv;
  178.  
  179.     img_base = load_image(path);
  180.  
  181.     if( ! img_base )
  182.         return 0;
  183.  
  184.     if( link_image( img_base ) )
  185.     {
  186.         dos = (PIMAGE_DOS_HEADER)img_base;
  187.         nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  188.  
  189.         drv_entry = MakePtr(drv_entry_t*, img_base,
  190.                             nt->OptionalHeader.AddressOfEntryPoint);
  191.  
  192.         srv = drv_entry(1);
  193.  
  194.         if(srv != NULL)
  195.             srv->entry = nt->OptionalHeader.AddressOfEntryPoint + img_base;
  196.  
  197.         return srv;
  198.     }
  199.     else
  200.     {
  201.         mem_free( img_base );
  202.         return NULL;
  203.     }
  204. }
  205.  
  206. typedef struct
  207. {
  208.     int a_type;
  209.     union
  210.     {
  211.         long  a_val;
  212.         void *a_ptr;
  213.         void  (*a_fcn)( ) ;
  214.     }a_un;
  215. }auxv_t;
  216.  
  217. #define AUX_COUNT       0
  218.  
  219. typedef struct
  220. {
  221.     int     argc;       /*  always 2                                */
  222.     char   *path;       /*  argv[0]   program path                  */
  223.     char   *cmdline;    /*  argv[1]   command  line. May be null    */
  224.     u32_t   sep1;       /*  separator.  must be zero                */
  225.     char   *env;        /*  single environment string               */
  226.     u32_t   sep2;       /*  separator.  must be zero                */
  227.     auxv_t  aux[1];     /*  aux. AT_NULL for now                    */
  228. }exec_stack_t;
  229.  
  230.  
  231. addr_t __fastcall pe_app_space(size_t size);
  232.  
  233. int __stdcall pe_app_param(char *path, void *raw, addr_t ex_pg_dir,
  234.                           exec_stack_t *ex_stack) asm ("pe_app_param");
  235.  
  236. int sys_exec(char *path, char *cmdline, u32_t flags)
  237. {
  238.     PIMAGE_DOS_HEADER     dos;
  239.     PIMAGE_NT_HEADERS32   nt;
  240.  
  241.     size_t   img_size;
  242.     count_t  img_pages;
  243.     count_t  img_tabs;
  244.     addr_t        ex_pg_dir;
  245.     addr_t        ex_stack_page;
  246.     addr_t        ex_pl0_stack;
  247.  
  248.     exec_stack_t *ex_stack;
  249.     int           stack_size;
  250.     char         *ex_path;
  251.     char         *ex_cmdline = NULL;
  252.  
  253.     size_t        raw_size;
  254.     u32_t        *raw;
  255.  
  256.     int pathsize = 0;
  257.     int cmdsize  = 0;
  258.     int envsize  = 0;
  259.  
  260.     u32_t tmp;
  261.  
  262.     DBG("\nexec %s cmd %s flags %x\n", path, cmdline, flags);
  263.  
  264.     if( ! path)
  265.     {
  266.         DBG("invalid path\n");
  267.         return;
  268.     };
  269.  
  270.     raw = load_file(path, &raw_size);
  271.  
  272.     if( ! raw )
  273.         return -5;                                      /* FIXME */
  274.  
  275.     if( (raw[0] == 0x554E454D) &&
  276.         ( ( raw[1] == 0x31305445) ||
  277.           ( raw[1] == 0x30305445) ) )
  278.  
  279.     {
  280.         DBG("leagacy Kolibri application\n");
  281.         int tmp =  mnt_exec(raw, raw_size, path, cmdline, flags);
  282.         DBG("pid %x\n",tmp);
  283.         return tmp;
  284.     }
  285.  
  286.     if( ! validate_pe(raw, raw_size, true) )
  287.     {
  288.         DBG("invalid executable file %s\n", path);
  289.         mem_free(raw);
  290.         return -31;
  291.     }
  292.  
  293.     dos = (PIMAGE_DOS_HEADER)raw;
  294.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  295.  
  296.     pathsize = strlen(path)+1;
  297.  
  298.     if( cmdline )
  299.         cmdsize = strlen(cmdline)+1;
  300.  
  301.     stack_size = sizeof(exec_stack_t) + pathsize +
  302.                  cmdsize + envsize + AUX_COUNT*sizeof(auxv_t);
  303.  
  304.     stack_size = (stack_size + 15) & ~15;               /* keep stack aligned */
  305.  
  306.     DBG("stacksize %d\n", stack_size);
  307.  
  308.     if( stack_size > 4096 )
  309.     {
  310.         DBG("command line too long\n");
  311.         return -30;
  312.     }
  313.  
  314.     ex_stack_page  = alloc_page();                   /* 2^0 = 1 page   */
  315.     if( ! ex_stack_page )
  316.     {
  317.         mem_free(raw);
  318.         return -30;                                    /* FIXME          */
  319.     };
  320.  
  321.     dos = (PIMAGE_DOS_HEADER)raw;
  322.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  323.  
  324.     img_size  =  nt->OptionalHeader.SizeOfImage;
  325.  
  326.     ex_pg_dir      = pe_app_space(img_size);
  327.  
  328.     if( !ex_pg_dir )
  329.     {
  330.         frame_free(ex_stack_page);
  331.         mem_free(raw);
  332.         return -30;                                    /* FIXME          */
  333.     };
  334.  
  335.     __asm__ __volatile__ (
  336.     "xorl %%eax, %%eax      \n\t"
  337.     "rep stosl"
  338.     :"=c"(tmp),"=D"(tmp)
  339.     :"c"(1024),"D"(ex_stack_page + OS_BASE)
  340.     :"eax","cc");
  341.  
  342.     ex_stack = (exec_stack_t*)(ex_stack_page + OS_BASE
  343.                                + PAGE_SIZE - stack_size);
  344.     ex_stack->argc = 2;
  345.  
  346.     ex_path = MakePtr(char*, ex_stack, sizeof(exec_stack_t)+AUX_COUNT*sizeof(auxv_t));
  347.  
  348.     memcpy(ex_path, path, pathsize);
  349.     ex_stack->path = (char*)(((addr_t)ex_path & 0xFFF) + 0x7FFFF000);  /* top of stack */
  350.  
  351.     if( cmdline )
  352.     {
  353.         ex_cmdline = ex_path + pathsize;
  354.         memcpy(ex_cmdline, cmdline, cmdsize);
  355.         ex_stack->cmdline = ex_stack->path + pathsize;
  356.     };
  357.  
  358. /*
  359.     ex_stack.env = null
  360.     ex_stack.aux[0] = AT_NULL
  361.  */
  362.  
  363.     DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n",
  364.          ex_stack, ex_stack->path, ex_stack->cmdline);
  365.  
  366.     return pe_app_param(path, raw, ex_pg_dir, ex_stack);
  367. };
  368.  
  369.  
  370. typedef struct
  371. {
  372.     u32_t edi;
  373.     u32_t esi;
  374.     u32_t ebp;
  375.     u32_t esp;
  376.     u32_t ebx;
  377.     u32_t edx;
  378.     u32_t ecx;
  379.     u32_t eax;
  380.     u32_t eip;
  381.     u32_t cs;
  382.     u32_t eflags;
  383.     u32_t pe_sp;
  384.     u32_t pe_ss;
  385. }thr_stack_t;
  386.  
  387. void sys_app_entry(addr_t raw, thr_stack_t *thr_stack, exec_stack_t *ex_stack)
  388. {
  389.     PIMAGE_DOS_HEADER     dos;
  390.     PIMAGE_NT_HEADERS32   nt;
  391.  
  392.     size_t   img_size;
  393.     count_t  img_pages;
  394.     size_t   stack_size;
  395.     addr_t   img_stack;
  396.     addr_t  *pte;
  397.  
  398.     count_t  i;
  399.     u32_t    tmp;
  400.  
  401.     __asm__ __volatile__ ("sti");
  402.  
  403.     dos = (PIMAGE_DOS_HEADER)raw;
  404.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  405.  
  406.     img_size  =  nt->OptionalHeader.SizeOfImage;
  407.  
  408.     current_slot->mem_size  = img_size;
  409.  
  410.     list_initialize(&current_slot->dll_list);
  411.  
  412.     pte = (addr_t*)page_tabs;
  413.     img_pages = img_size >> 12;
  414.  
  415.     stack_size = (nt->OptionalHeader.SizeOfStackReserve + 4095) & ~4095;
  416.     img_stack = 0x7FFFF000 - stack_size;
  417.     stack_size>>= 12;
  418.  
  419.     while (img_pages--)
  420.         *pte++ = 2;
  421.  
  422.     pte = &((addr_t*)page_tabs)[img_stack>>12];
  423.  
  424.     while(stack_size--)
  425.         *pte++ = 0x02;
  426.  
  427.     addr_t stack_page = ((addr_t)ex_stack-OS_BASE) & ~4095;
  428.  
  429.     *pte = stack_page | 7;
  430.  
  431.     create_image(0, raw, false);
  432.  
  433.     init_user_heap();
  434.  
  435.     if (! link_pe(0))
  436.     {
  437.         DBG("\nunresolved imports\nexit\n");
  438.         __asm__ __volatile__ (
  439.         "int $0x40"::"a"(-1));
  440.     };
  441.  
  442.  
  443.  //   __asm__ __volatile__ (
  444.  //   "xchgw %bx, %bx");
  445.  
  446.     addr_t entry = nt->OptionalHeader.AddressOfEntryPoint +
  447.                    nt->OptionalHeader.ImageBase;
  448.  
  449.     thr_stack->edi = 0;
  450.     thr_stack->esi = 0;
  451.     thr_stack->ebp = 0;
  452.     thr_stack->ebx = 0;
  453.     thr_stack->edx = 0;
  454.     thr_stack->ecx = 0;
  455.     thr_stack->eax = 0;
  456.     thr_stack->eip = entry;
  457.     thr_stack->cs  = sel_app_code;
  458.     thr_stack->eflags = EFL_IOPL3 | EFL_IF;
  459.     thr_stack->pe_sp = 0x7FFFF000 + ((u32_t)ex_stack & 0xFFF);
  460.     thr_stack->pe_ss = sel_app_data;
  461.  
  462. };
  463.  
  464. void* __stdcall user_alloc(size_t size) asm("user_alloc");
  465. void  __stdcall user_free(void *mem) asm("user_free");
  466.  
  467. dll_t* __fastcall load_dll(const char *path)
  468. {
  469.     PIMAGE_DOS_HEADER        dos;
  470.     PIMAGE_NT_HEADERS32      nt;
  471.     PIMAGE_EXPORT_DIRECTORY  exp;
  472.  
  473.     md_t    *img_md;
  474.  
  475.     size_t   img_size;
  476.     addr_t   img_base;
  477.     count_t  img_pages;
  478.  
  479.     size_t   raw_size = 0;
  480.     void    *raw;
  481.  
  482.     DBG("\nload dll %s", path);
  483.  
  484.     raw = load_file(path, &raw_size);
  485.  
  486.     DBG("  raw = %x\n", raw);
  487.  
  488.     if( ! raw)
  489.     {
  490.         DBG("file not found: %s\n", path);
  491.         return NULL;
  492.     };
  493.  
  494.     if( ! validate_pe(raw, raw_size, false) )
  495.     {
  496.         DBG("invalid pe file %s\n", path);
  497.         mem_free(raw);
  498.         return NULL;
  499.     }
  500.  
  501.     dos = (PIMAGE_DOS_HEADER)raw;
  502.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  503.  
  504.     img_size  =  nt->OptionalHeader.SizeOfImage;
  505.  
  506.     img_base = (addr_t)user_alloc(img_size);
  507.     if( !img_base)
  508.     {
  509.         mem_free(raw);
  510.         return NULL;
  511.     };
  512.  
  513.     dll_t *dll = (dll_t*)slab_alloc(dll_slab,0);         /* FIXME check */
  514.     if( !dll)
  515.     {
  516.         mem_free(raw);
  517.         user_free((void*)img_base);
  518.         return NULL;
  519.     };
  520.  
  521.     create_image(img_base, (addr_t)raw, false);
  522.  
  523.     mem_free(raw);
  524.  
  525.     dos = (PIMAGE_DOS_HEADER)img_base;
  526.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  527.     exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
  528.                    nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  529.  
  530.     dll->img_base = img_base;
  531.     dll->img_size = nt->OptionalHeader.SizeOfImage;
  532.     dll->img_md   = NULL;
  533.  
  534.     dll->img_hdr  = nt;
  535.     dll->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
  536.     dll->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
  537.                             nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  538.     dll->img_name = strupr(MakePtr(char*, img_base, exp->Name));
  539.  
  540.     list_insert(&current_slot->dll_list, &dll->link);
  541.  
  542.     return dll;
  543. };
  544.  
  545. bool link_pe(addr_t img_base)
  546. {
  547.     PIMAGE_DOS_HEADER     dos;
  548.     PIMAGE_NT_HEADERS32   nt;
  549.     char path[128];
  550.  
  551.     int warn = 0;
  552.  
  553. /* assumed that image is valid */
  554.  
  555.     dos = (PIMAGE_DOS_HEADER)img_base;
  556.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  557.  
  558.     if(nt->OptionalHeader.DataDirectory[1].Size)
  559.     {
  560.         PIMAGE_IMPORT_DESCRIPTOR imp;
  561.  
  562.         imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
  563.                       nt->OptionalHeader.DataDirectory[1].VirtualAddress);
  564.  
  565.         while ( 1 )
  566.         {
  567.             PIMAGE_THUNK_DATA32     thunk;
  568.  
  569.             PIMAGE_DOS_HEADER       expdos;
  570.             PIMAGE_NT_HEADERS32     expnt;
  571.             PIMAGE_EXPORT_DIRECTORY exp;
  572.  
  573.             u32_t   *iat;
  574.             char    *libname;
  575.             addr_t  *functions;
  576.             u16_t   *ordinals;
  577.             char   **funcname;
  578.  
  579.             dll_t   *exp_dll;
  580.  
  581.             if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
  582.                 break;
  583.  
  584.             libname=MakePtr(char*,imp->Name, img_base);
  585.  
  586.             DBG("import from %s\n",libname);
  587.  
  588.             exp_dll = find_dll(&core_dll.link, libname);
  589.             if(exp_dll == NULL)
  590.             {
  591.             exp_dll = find_dll(&current_slot->dll_list, libname);
  592.                 if(exp_dll == NULL)
  593.             {
  594.                 int len = strlen(libname)+1;
  595.  
  596.                 memcpy(path, "/sys/lib/",9);
  597.                 memcpy(&path[9],libname,len);
  598.  
  599.                 exp_dll = load_dll(path);
  600.                 if( !exp_dll)
  601.                 {
  602.                     DBG("can't load %s\n", path);
  603.                     return false;
  604.                 };
  605.             }
  606.             };
  607.             DBG("find %s\n", exp_dll->img_name);
  608.  
  609.             exp = exp_dll->img_exp;
  610.  
  611.             functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base);
  612.             ordinals = MakePtr(WORD*,  exp->AddressOfNameOrdinals,exp_dll->img_base);
  613.             funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base);
  614.  
  615.             thunk = MakePtr(PIMAGE_THUNK_DATA32,
  616.                             imp->Characteristics, img_base);
  617.             iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
  618.  
  619.             while ( 1 ) // Loop forever (or until we break out)
  620.             {
  621.                 PIMAGE_IMPORT_BY_NAME ord;
  622.                 addr_t addr;
  623.                 *iat=0;
  624.  
  625.                 if ( thunk->u1.AddressOfData == 0 )
  626.                     break;
  627.  
  628.                 if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
  629.                 {
  630.                    u16_t ordinal;
  631.                    ordinal = thunk->u1.Ordinal & 0xFFFF;
  632.                    *iat = functions[ordinal-exp->Base] + exp_dll->img_base;
  633.                     break;
  634.                 }
  635.                 else
  636.                 {
  637.                     ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
  638.                                   thunk->u1.AddressOfData, img_base);
  639.  
  640.                     DBG("import %s ", ord->Name);
  641.  
  642.                     if(strncmp(ord->Name,
  643.                        MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32))
  644.                     {
  645.                         int ind;
  646.                         char **names=funcname;
  647.  
  648.                         for(names = funcname,ind = 0;
  649.                             ind < exp->NumberOfNames; names++,ind++)
  650.                         {
  651.                             if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32))
  652.                             {
  653.                                 u16_t ordinal;
  654.                                 ordinal = ordinals[ind];
  655.                                 DBG("ordinal %d\t\tat %x\n", ordinal, functions[ordinal] + exp_dll->img_base);
  656.                                 *iat = functions[ordinal] + exp_dll->img_base;
  657.                                 break;
  658.                             };
  659.                         };
  660.                         if(ind == exp->NumberOfNames)
  661.                         {
  662.                             DBG(" unresolved import %s\n",ord->Name);
  663.                             warn=1;
  664.                         };
  665.                     }
  666.                     else
  667.                     {
  668.                         DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base);
  669.                         *iat = functions[ord->Hint] + exp_dll->img_base;
  670.                     };
  671.                 };
  672.                 thunk++;            // Advance to next thunk
  673.                 iat++;
  674.             }
  675.             imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
  676.         };
  677.     };
  678.  
  679.     if ( !warn )
  680.         return true;
  681.     else
  682.         return false;
  683. }
  684.  
  685.