Subversion Repositories Kolibri OS

Rev

Rev 1066 | 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.  
  239.     PIMAGE_DOS_HEADER     dos;
  240.     PIMAGE_NT_HEADERS32   nt;
  241.  
  242.     size_t   img_size;
  243.     count_t  img_pages;
  244.     count_t  img_tabs;
  245.  
  246.     addr_t        ex_pg_dir;
  247.     addr_t        ex_stack_page;
  248.     addr_t        ex_pl0_stack;
  249.  
  250.     exec_stack_t *ex_stack;
  251.     int           stack_size;
  252.     char         *ex_path;
  253.     char         *ex_cmdline = NULL;
  254.  
  255.     size_t        raw_size;
  256.     u32_t        *raw;
  257.  
  258.     int pathsize = 0;
  259.     int cmdsize  = 0;
  260.     int envsize  = 0;
  261.  
  262.     u32_t tmp;
  263.  
  264.     DBG("\nexec %s cmd %s flags %x\n", path, cmdline, flags);
  265.  
  266.     if( ! path)
  267.     {
  268.         DBG("invalid path\n");
  269.         return;
  270.     };
  271.  
  272.     raw = load_file(path, &raw_size);
  273.  
  274.     if( ! raw )
  275.         return -5;                                      /* FIXME */
  276.  
  277.     if( (raw[0] == 0x554E454D) &&
  278.         ( ( raw[1] == 0x31305445) ||
  279.           ( raw[1] == 0x30305445) ) )
  280.  
  281.     {
  282.         DBG("leagacy Kolibri application\n");
  283.         int tmp =  mnt_exec(raw, raw_size, path, cmdline, flags);
  284.         DBG("pid %x\n",tmp);
  285.         return tmp;
  286.     }
  287.  
  288.     if( ! validate_pe(raw, raw_size, true) )
  289.     {
  290.         DBG("invalid executable file %s\n", path);
  291.         mem_free(raw);
  292.         return -31;
  293.     }
  294.  
  295.     dos = (PIMAGE_DOS_HEADER)raw;
  296.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  297.  
  298.     pathsize = strlen(path)+1;
  299.  
  300.     if( cmdline )
  301.         cmdsize = strlen(cmdline)+1;
  302.  
  303.     stack_size = sizeof(exec_stack_t) + pathsize +
  304.                  cmdsize + envsize + AUX_COUNT*sizeof(auxv_t);
  305.  
  306.     stack_size = (stack_size + 15) & ~15;               /* keep stack aligned */
  307.  
  308.     DBG("stacksize %d\n", stack_size);
  309.  
  310.     if( stack_size > 4096 )
  311.     {
  312.         DBG("command line too long\n");
  313.         return -30;
  314.     }
  315.  
  316.     ex_stack_page  = alloc_page();                   /* 2^0 = 1 page   */
  317.     if( ! ex_stack_page )
  318.     {
  319.         mem_free(raw);
  320.         return -30;                                    /* FIXME          */
  321.     };
  322.  
  323.     dos = (PIMAGE_DOS_HEADER)raw;
  324.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  325.  
  326.     img_size  =  nt->OptionalHeader.SizeOfImage;
  327.  
  328.     ex_pg_dir      = pe_app_space(img_size);
  329.  
  330.     if( !ex_pg_dir )
  331.     {
  332.         frame_free(ex_stack_page);
  333.         mem_free(raw);
  334.         return -30;                                    /* FIXME          */
  335.     };
  336.  
  337.     __asm__ __volatile__ (
  338.     "xorl %%eax, %%eax      \n\t"
  339.     "rep stosl"
  340.     :"=c"(tmp),"=D"(tmp)
  341.     :"c"(1024),"D"(ex_stack_page + OS_BASE)
  342.     :"eax","cc");
  343.  
  344.     ex_stack = (exec_stack_t*)(ex_stack_page + OS_BASE
  345.                                + PAGE_SIZE - stack_size);
  346.     ex_stack->argc = 2;
  347.  
  348.     ex_path = MakePtr(char*, ex_stack, sizeof(exec_stack_t)+AUX_COUNT*sizeof(auxv_t));
  349.  
  350.     memcpy(ex_path, path, pathsize);
  351.     ex_stack->path = (char*)(((addr_t)ex_path & 0xFFF) + 0x7FFFF000);  /* top of stack */
  352.  
  353.     if( cmdline )
  354.     {
  355.         ex_cmdline = ex_path + pathsize;
  356.         memcpy(ex_cmdline, cmdline, cmdsize);
  357.         ex_stack->cmdline = ex_stack->path + pathsize;
  358.     };
  359.  
  360. /*
  361.     ex_stack.env = null
  362.     ex_stack.aux[0] = AT_NULL
  363.  */
  364.  
  365.     DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n",
  366.          ex_stack, ex_stack->path, ex_stack->cmdline);
  367.  
  368.     return pe_app_param(path, raw, ex_pg_dir, ex_stack);
  369. };
  370.  
  371.  
  372. typedef struct
  373. {
  374.     u32_t edi;
  375.     u32_t esi;
  376.     u32_t ebp;
  377.     u32_t esp;
  378.     u32_t ebx;
  379.     u32_t edx;
  380.     u32_t ecx;
  381.     u32_t eax;
  382.     u32_t eip;
  383.     u32_t cs;
  384.     u32_t eflags;
  385.     u32_t pe_sp;
  386.     u32_t pe_ss;
  387. }thr_stack_t;
  388.  
  389. void sys_app_entry(addr_t raw, thr_stack_t *thr_stack, exec_stack_t *ex_stack)
  390. {
  391.     PIMAGE_DOS_HEADER     dos;
  392.     PIMAGE_NT_HEADERS32   nt;
  393.  
  394.     size_t   img_size;
  395.     count_t  img_pages;
  396.     size_t   stack_size;
  397.     addr_t   img_stack;
  398.     addr_t  *pte;
  399.  
  400.     count_t  i;
  401.     u32_t    tmp;
  402.  
  403.     __asm__ __volatile__ ("sti");
  404.  
  405.     dos = (PIMAGE_DOS_HEADER)raw;
  406.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  407.  
  408.     img_size  =  nt->OptionalHeader.SizeOfImage;
  409.  
  410.     current_slot->mem_size  = img_size;
  411.  
  412.     list_initialize(&current_slot->dll_list);
  413.  
  414.     pte = (addr_t*)page_tabs;
  415.     img_pages = img_size >> 12;
  416.  
  417.     stack_size = (nt->OptionalHeader.SizeOfStackReserve + 4095) & ~4095;
  418.     img_stack = 0x7FFFF000 - stack_size;
  419.     stack_size>>= 12;
  420.  
  421.     while (img_pages--)
  422.         *pte++ = 2;
  423.  
  424.     pte = &((addr_t*)page_tabs)[img_stack>>12];
  425.  
  426.     while(stack_size--)
  427.         *pte++ = 0x02;
  428.  
  429.     addr_t stack_page = ((addr_t)ex_stack-OS_BASE) & ~4095;
  430.  
  431.     *pte = stack_page | 7;
  432.  
  433.     create_image(0, raw, false);
  434.  
  435.     init_user_heap();
  436.  
  437.     if (! link_pe(0))
  438.     {
  439.         DBG("\nunresolved imports\nexit\n");
  440.         __asm__ __volatile__ (
  441.         "int $0x40"::"a"(-1));
  442.     };
  443.  
  444.  
  445.  //   __asm__ __volatile__ (
  446.  //   "xchgw %bx, %bx");
  447.  
  448.     addr_t entry = nt->OptionalHeader.AddressOfEntryPoint +
  449.                    nt->OptionalHeader.ImageBase;
  450.  
  451.     thr_stack->edi = 0;
  452.     thr_stack->esi = 0;
  453.     thr_stack->ebp = 0;
  454.     thr_stack->ebx = 0;
  455.     thr_stack->edx = 0;
  456.     thr_stack->ecx = 0;
  457.     thr_stack->eax = 0;
  458.     thr_stack->eip = entry;
  459.     thr_stack->cs  = sel_app_code;
  460.     thr_stack->eflags = EFL_IOPL3 | EFL_IF;
  461.     thr_stack->pe_sp = 0x7FFFF000 + ((u32_t)ex_stack & 0xFFF);
  462.     thr_stack->pe_ss = sel_app_data;
  463.  
  464. };
  465.  
  466. void* __stdcall user_alloc(size_t size) asm("user_alloc");
  467. void  __stdcall user_free(void *mem) asm("user_free");
  468.  
  469. dll_t* __fastcall load_dll(const char *path)
  470. {
  471.     PIMAGE_DOS_HEADER        dos;
  472.     PIMAGE_NT_HEADERS32      nt;
  473.     PIMAGE_EXPORT_DIRECTORY  exp;
  474.  
  475.     md_t    *img_md;
  476.  
  477.     size_t   img_size;
  478.     addr_t   img_base;
  479.     count_t  img_pages;
  480.  
  481.     size_t   raw_size = 0;
  482.     void    *raw;
  483.  
  484.     DBG("\nload dll %s", path);
  485.  
  486.     raw = load_file(path, &raw_size);
  487.  
  488.     DBG("  raw = %x\n", raw);
  489.  
  490.     if( ! raw)
  491.     {
  492.         DBG("file not found: %s\n", path);
  493.         return NULL;
  494.     };
  495.  
  496.     if( ! validate_pe(raw, raw_size, false) )
  497.     {
  498.         DBG("invalid pe file %s\n", path);
  499.         mem_free(raw);
  500.         return NULL;
  501.     }
  502.  
  503.     dos = (PIMAGE_DOS_HEADER)raw;
  504.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  505.  
  506.     img_size  =  nt->OptionalHeader.SizeOfImage;
  507.  
  508.     img_base = (addr_t)user_alloc(img_size);
  509.     if( !img_base)
  510.     {
  511.         mem_free(raw);
  512.         return NULL;
  513.     };
  514.  
  515.     dll_t *dll = (dll_t*)slab_alloc(dll_slab,0);         /* FIXME check */
  516.     if( !dll)
  517.     {
  518.         mem_free(raw);
  519.         user_free((void*)img_base);
  520.         return NULL;
  521.     };
  522.  
  523.     create_image(img_base, (addr_t)raw, false);
  524.  
  525.     mem_free(raw);
  526.  
  527.     dos = (PIMAGE_DOS_HEADER)img_base;
  528.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  529.     exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
  530.                    nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  531.  
  532.     dll->img_base = img_base;
  533.     dll->img_size = nt->OptionalHeader.SizeOfImage;
  534.     dll->img_md   = NULL;
  535.  
  536.     dll->img_hdr  = nt;
  537.     dll->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
  538.     dll->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
  539.                             nt->OptionalHeader.DataDirectory[0].VirtualAddress);
  540.     dll->img_name = strupr(MakePtr(char*, img_base, exp->Name));
  541.  
  542.     list_insert(&current_slot->dll_list, &dll->link);
  543.  
  544.     return dll;
  545. };
  546.  
  547. bool link_pe(addr_t img_base)
  548. {
  549.     PIMAGE_DOS_HEADER     dos;
  550.     PIMAGE_NT_HEADERS32   nt;
  551.     char path[128];
  552.  
  553.     int warn = 0;
  554.  
  555. /* assumed that image is valid */
  556.  
  557.     dos = (PIMAGE_DOS_HEADER)img_base;
  558.     nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
  559.  
  560.     if(nt->OptionalHeader.DataDirectory[1].Size)
  561.     {
  562.         PIMAGE_IMPORT_DESCRIPTOR imp;
  563.  
  564.         imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
  565.                       nt->OptionalHeader.DataDirectory[1].VirtualAddress);
  566.  
  567.         while ( 1 )
  568.         {
  569.             PIMAGE_THUNK_DATA32     thunk;
  570.  
  571.             PIMAGE_DOS_HEADER       expdos;
  572.             PIMAGE_NT_HEADERS32     expnt;
  573.             PIMAGE_EXPORT_DIRECTORY exp;
  574.  
  575.             u32_t   *iat;
  576.             char    *libname;
  577.             addr_t  *functions;
  578.             u16_t   *ordinals;
  579.             char   **funcname;
  580.  
  581.             dll_t   *exp_dll;
  582.  
  583.             if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
  584.                 break;
  585.  
  586.             libname=MakePtr(char*,imp->Name, img_base);
  587.  
  588.             DBG("import from %s\n",libname);
  589.  
  590.             exp_dll = find_dll(&core_dll.link, libname);
  591.             if(exp_dll == NULL)
  592.             {
  593.  
  594.             exp_dll = find_dll(&current_slot->dll_list, libname);
  595.                 if(exp_dll == NULL)
  596.             {
  597.                 int len = strlen(libname)+1;
  598.  
  599.                 memcpy(path, "/sys/lib/",9);
  600.                 memcpy(&path[9],libname,len);
  601.  
  602.                 exp_dll = load_dll(path);
  603.                 if( !exp_dll)
  604.                 {
  605.                     DBG("can't load %s\n", path);
  606.                     return false;
  607.                 };
  608.             }
  609.             };
  610.             DBG("find %s\n", exp_dll->img_name);
  611.  
  612.             exp = exp_dll->img_exp;
  613.  
  614.             functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base);
  615.             ordinals = MakePtr(WORD*,  exp->AddressOfNameOrdinals,exp_dll->img_base);
  616.             funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base);
  617.  
  618.             thunk = MakePtr(PIMAGE_THUNK_DATA32,
  619.                             imp->Characteristics, img_base);
  620.             iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
  621.  
  622.             while ( 1 ) // Loop forever (or until we break out)
  623.             {
  624.                 PIMAGE_IMPORT_BY_NAME ord;
  625.                 addr_t addr;
  626.                 *iat=0;
  627.  
  628.                 if ( thunk->u1.AddressOfData == 0 )
  629.                     break;
  630.  
  631.                 if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
  632.                 {
  633.                    u16_t ordinal;
  634.                    ordinal = thunk->u1.Ordinal & 0xFFFF;
  635.                    *iat = functions[ordinal-exp->Base] + exp_dll->img_base;
  636.                     break;
  637.                 }
  638.                 else
  639.                 {
  640.                     ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
  641.                                   thunk->u1.AddressOfData, img_base);
  642.  
  643.                     DBG("import %s ", ord->Name);
  644.  
  645.                     if(strncmp(ord->Name,
  646.                        MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32))
  647.                     {
  648.                         int ind;
  649.                         char **names=funcname;
  650.  
  651.                         for(names = funcname,ind = 0;
  652.                             ind < exp->NumberOfNames; names++,ind++)
  653.                         {
  654.                             if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32))
  655.                             {
  656.                                 u16_t ordinal;
  657.                                 ordinal = ordinals[ind];
  658.                                 DBG("ordinal %d\t\tat %x\n", ordinal, functions[ordinal] + exp_dll->img_base);
  659.                                 *iat = functions[ordinal] + exp_dll->img_base;
  660.                                 break;
  661.                             };
  662.                         };
  663.                         if(ind == exp->NumberOfNames)
  664.                         {
  665.                             DBG(" unresolved import %s\n",ord->Name);
  666.                             warn=1;
  667.                         };
  668.                     }
  669.                     else
  670.                     {
  671.                         DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base);
  672.                         *iat = functions[ord->Hint] + exp_dll->img_base;
  673.                     };
  674.                 };
  675.                 thunk++;            // Advance to next thunk
  676.                 iat++;
  677.             }
  678.             imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
  679.         };
  680.     };
  681.  
  682.     if ( !warn )
  683.         return true;
  684.     else
  685.         return false;
  686. }
  687.  
  688.