Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
win_api_x86_32.py
Go to the documentation of this file.
1 #
2 # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 #
18 import struct
19 import inspect
20 import os
21 import stat
22 import time
23 import string
24 import logging
25 from zlib import crc32
26 from StringIO import StringIO
27 
28 try:
29  from Crypto.Hash import MD5, SHA
30 except ImportError:
31  print "cannot find crypto, skipping"
32 
33 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC
34 from miasm2.core.utils import pck16, pck32, upck32, hexdump
35 from miasm2.os_dep.common import \
36  heap, set_str_ansi, set_str_unic, get_str_ansi, get_str_unic, \
37  windows_to_sbpath
38 from miasm2.os_dep.win_api_x86_32_seh import FS_0_AD
39 
40 log = logging.getLogger("win_api_x86_32")
41 console_handler = logging.StreamHandler()
42 console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
43 log.addHandler(console_handler)
44 log.setLevel(logging.WARN)
45 
46 
47 MAX_PATH = 260
48 
49 
50 """
51 typedef struct tagPROCESSENTRY32 {
52  DWORD dwSize;
53  DWORD cntUsage;
54  DWORD th32ProcessID;
55  ULONG_PTR th32DefaultHeapID;
56  DWORD th32ModuleID;
57  DWORD cntThreads;
58  DWORD th32ParentProcessID;
59  LONG pcPriClassBase;
60  DWORD dwFlags;
61  TCHAR szExeFile[MAX_PATH];
62 } PROCESSENTRY32, *PPROCESSENTRY32;
63 """
64 
65 
66 access_dict = {0x0: 0,
67  0x1: 0,
68  0x2: PAGE_READ,
69  0x4: PAGE_READ | PAGE_WRITE,
70  0x10: PAGE_EXEC,
71  0x20: PAGE_EXEC | PAGE_READ,
72  0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
73  0x80: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
74  # 0x80: PAGE_EXECUTE_WRITECOPY
75  0x100: 0
76  }
77 
78 access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
79 
80 
81 class whandle():
82 
83  def __init__(self, name, info):
84  self.name = name
85  self.info = info
86 
87  def __repr__(self):
88  return '<%r %r %r>' % (self.__class__.__name__, self.name, self.info)
89 
90 
92 
93  def __init__(self):
94  self.offset = 600
95  self.all_handles = {}
96 
97  def add(self, name, info=None):
98  self.offset += 1
99  h = whandle(name, info)
100  self.all_handles[self.offset] = h
101 
102  log.debug(repr(self))
103  return self.offset
104 
105  def __repr__(self):
106  out = '<%r\n' % self.__class__.__name__
107  ks = self.all_handles.keys()
108  ks.sort()
109 
110  for k in ks:
111  out += " %r %r\n" % (k, self.all_handles[k])
112  out += '>'
113  return out
114 
115  def __contains__(self, e):
116  return e in self.all_handles
117 
118  def __getitem__(self, item):
119  return self.all_handles.__getitem__(item)
120 
121  def __delitem__(self, item):
122  self.all_handles.__delitem__(item)
123 
124 
125 class c_winobjs:
126 
127  def __init__(self):
128  self.alloc_ad = 0x20000000
129  self.alloc_align = 0x1000
130  self.heap = heap()
131  self.handle_toolhelpsnapshot = 0xaaaa00
133  self.handle_curprocess = 0xaaaa01
134  self.dbg_present = 0
135  self.tickcount = 0
136  self.dw_pid_dummy1 = 0x111
137  self.dw_pid_explorer = 0x222
138  self.dw_pid_dummy2 = 0x333
139  self.dw_pid_cur = 0x444
140  self.module_fname_nux = None
141  self.module_name = "test.exe"
142  self.module_path = "c:\\mydir\\" + self.module_name
143  self.hcurmodule = None
144  self.module_filesize = None
145  self.getversion = 0x0A280105
146  self.getforegroundwindow = 0x333333
147  self.cryptcontext_hwnd = 0x44400
148  self.cryptcontext_bnum = 0x44000
150  self.cryptcontext = {}
151  self.phhash_crypt_md5 = 0x55555
152  self.files_hwnd = {}
153  self.windowlong_dw = 0x77700
154  self.module_cur_hwnd = 0x88800
155  self.module_file_nul = 0x999000
156  self.runtime_dll = None
157  self.current_pe = None
158  self.tls_index = 0xf
159  self.tls_values = {}
161  self.handle_mapped = {}
162  self.hkey_handles = {0x80000001: "hkey_current_user"}
163 
164  self.nt_mdl = {}
165  self.nt_mdl_ad = None
166  self.nt_mdl_cur = 0
167  self.win_event_num = 0x13370
168  self.cryptdll_md5_h = {}
169 
170  self.lastwin32error = 0
171  self.mutex = {}
172  self.env_variables = {}
173  self.events_pool = {}
174  self.find_data = None
175 winobjs = c_winobjs()
176 
177 
178 process_list = [
179  [
180  0x40, # DWORD dwSize;
181  0, # DWORD cntUsage;
182  winobjs.dw_pid_dummy1, # DWORD th32ProcessID;
183  0x11111111, # ULONG_PTR th32DefaultHeapID;
184  0x11111112, # DWORD th32ModuleID;
185  1, # DWORD cntThreads;
186  winobjs.dw_pid_explorer, # DWORD th32ParentProcessID;
187  0xbeef, # LONG pcPriClassBase;
188  0x0, # DWORD dwFlags;
189  "dummy1.exe" # TCHAR szExeFile[MAX_PATH];
190  ],
191  [
192  0x40, # DWORD dwSize;
193  0, # DWORD cntUsage;
194  winobjs.dw_pid_explorer, # DWORD th32ProcessID;
195  0x11111111, # ULONG_PTR th32DefaultHeapID;
196  0x11111112, # DWORD th32ModuleID;
197  1, # DWORD cntThreads;
198  4, # DWORD th32ParentProcessID;
199  0xbeef, # LONG pcPriClassBase;
200  0x0, # DWORD dwFlags;
201  "explorer.exe" # TCHAR szExeFile[MAX_PATH];
202  ],
203 
204  [
205  0x40, # DWORD dwSize;
206  0, # DWORD cntUsage;
207  winobjs.dw_pid_dummy2, # DWORD th32ProcessID;
208  0x11111111, # ULONG_PTR th32DefaultHeapID;
209  0x11111112, # DWORD th32ModuleID;
210  1, # DWORD cntThreads;
211  winobjs.dw_pid_explorer, # DWORD th32ParentProcessID;
212  0xbeef, # LONG pcPriClassBase;
213  0x0, # DWORD dwFlags;
214  "dummy2.exe" # TCHAR szExeFile[MAX_PATH];
215  ],
216 
217  [
218  0x40, # DWORD dwSize;
219  0, # DWORD cntUsage;
220  winobjs.dw_pid_cur, # DWORD th32ProcessID;
221  0x11111111, # ULONG_PTR th32DefaultHeapID;
222  0x11111112, # DWORD th32ModuleID;
223  1, # DWORD cntThreads;
224  winobjs.dw_pid_explorer, # DWORD th32ParentProcessID;
225  0xbeef, # LONG pcPriClassBase;
226  0x0, # DWORD dwFlags;
227  winobjs.module_name # TCHAR szExeFile[MAX_PATH];
228  ],
229 
230 
231 ]
232 
233 
234 def whoami():
235  return inspect.stack()[1][3]
236 
237 
238 class hobj:
239  pass
240 
241 
242 class mdl:
243 
244  def __init__(self, ad, l):
245  self.ad = ad
246  self.l = l
247 
248  def __str__(self):
249  return struct.pack('LL', self.ad, self.l)
250 
251 
252 def kernel32_HeapAlloc(jitter):
253  ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"])
254  alloc_addr = winobjs.heap.alloc(jitter, args.size)
255  jitter.func_ret_stdcall(ret_ad, alloc_addr)
256 
257 
258 def kernel32_HeapFree(jitter):
259  ret_ad, _ = jitter.func_args_stdcall(["heap", "flags", "pmem"])
260  jitter.func_ret_stdcall(ret_ad, 1)
261 
262 
264  ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"])
265  alloc_addr = winobjs.heap.alloc(jitter, args.msize)
266  jitter.func_ret_stdcall(ret_ad, alloc_addr)
267 
268 
269 def kernel32_LocalFree(jitter):
270  ret_ad, _ = jitter.func_args_stdcall(["lpvoid"])
271  jitter.func_ret_stdcall(ret_ad, 0)
272 
273 
275  ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"])
276  alloc_addr = winobjs.heap.alloc(jitter, args.msize)
277  jitter.func_ret_stdcall(ret_ad, alloc_addr)
278 
279 
281  ret_ad, _ = jitter.func_args_stdcall(["addr"])
282  jitter.func_ret_stdcall(ret_ad, 0)
283 
284 
286  ret_ad, _ = jitter.func_args_stdcall(0)
287  jitter.func_ret_stdcall(ret_ad, winobjs.dbg_present)
288 
289 
291  ret_ad, _ = jitter.func_args_stdcall(["dwflags", "th32processid"])
292  jitter.func_ret_stdcall(ret_ad, winobjs.handle_toolhelpsnapshot)
293 
294 
296  ret_ad, _ = jitter.func_args_stdcall(0)
297  jitter.func_ret_stdcall(ret_ad, winobjs.handle_curprocess)
298 
299 
301  ret_ad, _ = jitter.func_args_stdcall(0)
302  jitter.func_ret_stdcall(ret_ad, winobjs.dw_pid_cur)
303 
304 
306  ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
307 
308  pentry = struct.pack(
309  'IIIIIIIII', *process_list[0][:-1]) + process_list[0][-1]
310  jitter.vm.set_mem(args.ad_pentry, pentry)
311  winobjs.toolhelpsnapshot_info[args.s_handle] = 0
312 
313  jitter.func_ret_stdcall(ret_ad, 1)
314 
315 
317  ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
318 
319  winobjs.toolhelpsnapshot_info[args.s_handle] += 1
320  if winobjs.toolhelpsnapshot_info[args.s_handle] >= len(process_list):
321  ret = 0
322  else:
323  ret = 1
324  n = winobjs.toolhelpsnapshot_info[args.s_handle]
325  pentry = struct.pack(
326  'IIIIIIIII', *process_list[n][:-1]) + process_list[n][-1]
327  jitter.vm.set_mem(args.ad_pentry, pentry)
328  jitter.func_ret_stdcall(ret_ad, ret)
329 
330 
332  ret_ad, _ = jitter.func_args_stdcall(0)
333  winobjs.tickcount += 1
334  jitter.func_ret_stdcall(ret_ad, winobjs.tickcount)
335 
336 
338  ret_ad, _ = jitter.func_args_stdcall(0)
339  jitter.func_ret_stdcall(ret_ad, winobjs.getversion)
340 
341 
342 def kernel32_GetVersionEx(jitter, set_str=set_str_unic):
343  ret_ad, args = jitter.func_args_stdcall(["ptr_struct"])
344 
345  s = struct.pack("IIIII",
346  0x114, # struct size
347  0x5, # maj vers
348  0x2, # min vers
349  0xa28, # build nbr
350  0x2, # platform id
351  )
352  t = set_str("Service pack 4")
353  t = s + (t + '\x00' * 128 * 2)[:128 * 2]
354  t += struct.pack('HHHBB', 3, 0, 0x100, 1, 0)
355  s = t
356  jitter.vm.set_mem(args.ptr_struct, s)
357  jitter.func_ret_stdcall(ret_ad, 1)
358 
359 
360 kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter,
361  set_str_ansi)
362 kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter,
363  set_str_unic)
364 
365 
367  ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
368  jitter.func_ret_stdcall(ret_ad, 0)
369 
370 
372  ret_ad, _ = jitter.func_args_stdcall(["hwnd", "dwpclass"])
373  jitter.func_ret_stdcall(ret_ad, 0)
374 
375 
377  ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
378  jitter.func_ret_stdcall(ret_ad, 1)
379 
380 
382  ret_ad, _ = jitter.func_args_stdcall(0)
383  jitter.func_ret_stdcall(ret_ad, winobjs.getforegroundwindow)
384 
385 
386 def user32_FindWindowA(jitter):
387  ret_ad, _ = jitter.func_args_stdcall(["pclassname", "pwindowname"])
388  jitter.func_ret_stdcall(ret_ad, 0)
389 
390 
392  ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
393  jitter.func_ret_stdcall(ret_ad, 0)
394 
395 
396 def user32_BlockInput(jitter):
397  ret_ad, _ = jitter.func_args_stdcall(["blockit"])
398  jitter.func_ret_stdcall(ret_ad, 1)
399 
400 
401 def advapi32_CryptAcquireContext(jitter, funcname, get_str):
402  ret_ad, args = jitter.func_args_stdcall(["phprov", "pszcontainer",
403  "pszprovider", "dwprovtype",
404  "dwflags"])
405  prov = get_str(jitter, args.pszprovider) if args.pszprovider else "NONE"
406  log.debug('prov: %r', prov)
407  jitter.vm.set_mem(args.phprov, pck32(winobjs.cryptcontext_hwnd))
408  jitter.func_ret_stdcall(ret_ad, 1)
409 
410 
412  advapi32_CryptAcquireContext(jitter, whoami(), get_str_ansi)
413 
414 
416  advapi32_CryptAcquireContext(jitter, whoami(), get_str_unic)
417 
418 
420  ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hkey",
421  "dwflags", "phhash"])
422 
423  winobjs.cryptcontext_num += 1
424 
425  if args.algid == 0x00008003:
426  log.debug('algo is MD5')
427  jitter.vm.set_mem(
428  args.phhash,
429  pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num)
430  )
431  winobjs.cryptcontext[
432  winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj()
433  winobjs.cryptcontext[
434  winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = MD5.new()
435  elif args.algid == 0x00008004:
436  log.debug('algo is SHA1')
437  jitter.vm.set_mem(
438  args.phhash,
439  pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num)
440  )
441  winobjs.cryptcontext[
442  winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj()
443  winobjs.cryptcontext[
444  winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = SHA.new()
445  else:
446  raise ValueError('un impl algo1')
447  jitter.func_ret_stdcall(ret_ad, 1)
448 
449 
451  ret_ad, args = jitter.func_args_stdcall(["hhash", "pbdata", "dwdatalen",
452  "dwflags"])
453 
454  if not args.hhash in winobjs.cryptcontext:
455  raise ValueError("unknown crypt context")
456 
457  data = jitter.vm.get_mem(args.pbdata, args.dwdatalen)
458  log.debug('will hash %X', args.dwdatalen)
459  log.debug(repr(data[:10]) + "...")
460  winobjs.cryptcontext[args.hhash].h.update(data)
461  jitter.func_ret_stdcall(ret_ad, 1)
462 
463 
465  ret_ad, args = jitter.func_args_stdcall(["hhash", "param", "pbdata",
466  "dwdatalen", "dwflags"])
467 
468  if not args.hhash in winobjs.cryptcontext:
469  raise ValueError("unknown crypt context")
470 
471  if args.param == 2:
472  # XXX todo: save h state?
473  h = winobjs.cryptcontext[args.hhash].h.digest()
474  else:
475  raise ValueError('not impl', args.param)
476  jitter.vm.set_mem(args.pbdata, h)
477  jitter.vm.set_mem(args.dwdatalen, pck32(len(h)))
478 
479  jitter.func_ret_stdcall(ret_ad, 1)
480 
481 
483  ret_ad, _ = jitter.func_args_stdcall(["hhash", "flags"])
484  jitter.func_ret_stdcall(ret_ad, 0)
485 
486 
488  ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hbasedata",
489  "dwflags", "phkey"])
490 
491  if args.algid == 0x6801:
492  log.debug('using DES')
493  else:
494  raise ValueError('un impl algo2')
495  h = winobjs.cryptcontext[args.hbasedata].h.digest()
496  log.debug('hash %r', h)
497  winobjs.cryptcontext[args.hbasedata].h_result = h
498  jitter.vm.set_mem(args.phkey, pck32(args.hbasedata))
499  jitter.func_ret_stdcall(ret_ad, 1)
500 
501 
503  ret_ad, _ = jitter.func_args_stdcall(["hhash"])
504  jitter.func_ret_stdcall(ret_ad, 1)
505 
506 
508  ret_ad, _ = jitter.func_args_stdcall(["hkey", "hhash", "final",
509  "dwflags", "pbdata",
510  "pdwdatalen"])
511  raise ValueError("Not implemented")
512  # jitter.func_ret_stdcall(ret_ad, 1)
513 
514 
515 def kernel32_CreateFile(jitter, funcname, get_str):
516  ret_ad, args = jitter.func_args_stdcall(["lpfilename", "access",
517  "dwsharedmode",
518  "lpsecurityattr",
519  "dwcreationdisposition",
520  "dwflagsandattr",
521  "htemplatefile"])
522  if args.lpfilename == 0:
523  jitter.func_ret_stdcall(ret_ad, 0xffffffff)
524  return
525 
526  fname = get_str(jitter, args.lpfilename)
527  log.debug('fname %s', fname)
528  ret = 0xffffffff
529 
530  log.debug("%r %r", fname.lower(), winobjs.module_path.lower())
531  is_original_file = fname.lower() == winobjs.module_path.lower()
532 
533  if fname.upper() in [r"\\.\SICE", r"\\.\NTICE", r"\\.\SIWVID"]:
534  pass
535  elif fname.upper() in ['NUL']:
536  ret = winobjs.module_cur_hwnd
537  else:
538  # sandox path
539  sb_fname = windows_to_sbpath(fname)
540  if args.access & 0x80000000 or args.access == 1:
541  # read
542  if args.dwcreationdisposition == 2:
543  # create_always
544  if os.access(sb_fname, os.R_OK):
545  # but file exist
546  pass
547  else:
548  raise NotImplementedError("Untested case") # to test
549  # h = open(sb_fname, 'rb+')
550  elif args.dwcreationdisposition == 3:
551  # open_existing
552  if os.access(sb_fname, os.R_OK):
553  s = os.stat(sb_fname)
554  if stat.S_ISDIR(s.st_mode):
555  ret = winobjs.handle_pool.add(sb_fname, 0x1337)
556  else:
557  h = open(sb_fname, 'r+b')
558  ret = winobjs.handle_pool.add(sb_fname, h)
559  else:
560  log.warning("FILE %r DOES NOT EXIST!", fname)
561  elif args.dwcreationdisposition == 1:
562  # create new
563  if os.access(sb_fname, os.R_OK):
564  # file exist
565  # ret = 80
566  winobjs.lastwin32error = 80
567  else:
568  # first create an empty file
569  open(sb_fname, 'w').close()
570  # then open
571  h = open(sb_fname, 'r+b')
572  ret = winobjs.handle_pool.add(sb_fname, h)
573  elif args.dwcreationdisposition == 4:
574  # open_always
575  if os.access(sb_fname, os.R_OK):
576  s = os.stat(sb_fname)
577  if stat.S_ISDIR(s.st_mode):
578  ret = winobjs.handle_pool.add(sb_fname, 0x1337)
579  else:
580  h = open(sb_fname, 'r+b')
581  ret = winobjs.handle_pool.add(sb_fname, h)
582  else:
583  raise NotImplementedError("Untested case")
584  else:
585  raise NotImplementedError("Untested case")
586  elif args.access & 0x40000000:
587  # write
588  if args.dwcreationdisposition == 3:
589  # open existing
590  if is_original_file:
591  # cannot open self in write mode!
592  pass
593  elif os.access(sb_fname, os.R_OK):
594  s = os.stat(sb_fname)
595  if stat.S_ISDIR(s.st_mode):
596  # open dir
597  ret = winobjs.handle_pool.add(sb_fname, 0x1337)
598  else:
599  h = open(sb_fname, 'r+b')
600  ret = winobjs.handle_pool.add(sb_fname, h)
601  else:
602  raise NotImplementedError("Untested case") # to test
603  elif args.dwcreationdisposition == 5:
604  # truncate_existing
605  if is_original_file:
606  pass
607  else:
608  raise NotImplementedError("Untested case") # to test
609  else:
610  # raise NotImplementedError("Untested case") # to test
611  h = open(sb_fname, 'w')
612  ret = winobjs.handle_pool.add(sb_fname, h)
613  else:
614  raise NotImplementedError("Untested case")
615 
616  # h = open(sb_fname, 'rb+')
617  # ret = winobjs.handle_pool.add(sb_fname, h)
618  log.debug('ret %x', ret)
619  jitter.func_ret_stdcall(ret_ad, ret)
620 
621 
623  kernel32_CreateFile(jitter, whoami(), get_str_ansi)
624 
625 
627  kernel32_CreateFile(jitter, whoami(), lambda x, y: get_str_unic(jitter, y))
628 
629 
630 def kernel32_ReadFile(jitter):
631  ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
632  "nnumberofbytestoread",
633  "lpnumberofbytesread",
634  "lpoverlapped"])
635  if args.hwnd == winobjs.module_cur_hwnd:
636  pass
637  elif args.hwnd in winobjs.handle_pool:
638  pass
639  else:
640  raise ValueError('unknown hwnd!')
641 
642  data = None
643  if args.hwnd in winobjs.files_hwnd:
644  data = winobjs.files_hwnd[
645  winobjs.module_cur_hwnd].read(args.nnumberofbytestoread)
646  elif args.hwnd in winobjs.handle_pool:
647  wh = winobjs.handle_pool[args.hwnd]
648  data = wh.info.read(args.nnumberofbytestoread)
649  else:
650  raise ValueError('unknown filename')
651 
652  if data is not None:
653  if (args.lpnumberofbytesread):
654  jitter.vm.set_mem(args.lpnumberofbytesread, pck32(len(data)))
655  jitter.vm.set_mem(args.lpbuffer, data)
656 
657  jitter.func_ret_stdcall(ret_ad, 1)
658 
659 
661  ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
662 
663  if args.hwnd == winobjs.module_cur_hwnd:
664  ret = len(open(winobjs.module_fname_nux).read())
665  elif args.hwnd in winobjs.handle_pool:
666  wh = winobjs.handle_pool[args.hwnd]
667  ret = len(open(wh.name).read())
668  else:
669  raise ValueError('unknown hwnd!')
670 
671  if args.lpfilesizehight != 0:
672  jitter.vm.set_mem(args.lpfilesizehight, pck32(ret))
673  jitter.func_ret_stdcall(ret_ad, ret)
674 
675 
677  ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
678 
679  if args.hwnd == winobjs.module_cur_hwnd:
680  l = len(open(winobjs.module_fname_nux).read())
681  elif args.hwnd in winobjs.handle_pool:
682  wh = winobjs.handle_pool[args.hwnd]
683  l = len(open(wh.name).read())
684  else:
685  raise ValueError('unknown hwnd!')
686 
687  if args.lpfilesizehight == 0:
688  raise NotImplementedError("Untested case")
689  jitter.vm.set_mem(args.lpfilesizehight, pck32(
690  l & 0xffffffff) + pck32((l >> 32) & 0xffffffff))
691  jitter.func_ret_stdcall(ret_ad, 1)
692 
693 
695  ret_ad, _ = jitter.func_args_stdcall(["hprocess", "lpbasead", "dwsize"])
696  jitter.func_ret_stdcall(ret_ad, 0x1337)
697 
698 
700  ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
701  'flnewprotect',
702  'lpfloldprotect'])
703  # XXX mask hpart
704  flnewprotect = args.flnewprotect & 0xFFF
705  if not flnewprotect in access_dict:
706  raise ValueError('unknown access dw!')
707  jitter.vm.set_mem_access(args.lpvoid, access_dict[flnewprotect])
708 
709  # XXX todo real old protect
710  if args.lpfloldprotect:
711  jitter.vm.set_mem(args.lpfloldprotect, pck32(0x40))
712 
713  jitter.func_ret_stdcall(ret_ad, 1)
714 
715 
717  ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
718  'alloc_type', 'flprotect'])
719 
720  access_dict = {
721  0x0: 0,
722  0x1: 0,
723  0x2: PAGE_READ,
724  0x4: PAGE_READ | PAGE_WRITE,
725  0x10: PAGE_EXEC,
726  0x20: PAGE_EXEC | PAGE_READ,
727  0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
728  0x100: 0,
729  }
730 
731  # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
732 
733  if not args.flprotect in access_dict:
734  raise ValueError('unknown access dw!')
735 
736  if args.lpvoid == 0:
737  alloc_addr = winobjs.heap.next_addr(args.dwsize)
738  jitter.vm.add_memory_page(
739  alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize)
740  else:
741  all_mem = jitter.vm.get_all_memory()
742  if args.lpvoid in all_mem:
743  alloc_addr = args.lpvoid
744  jitter.vm.set_mem_access(args.lpvoid, access_dict[args.flprotect])
745  else:
746  alloc_addr = winobjs.heap.next_addr(args.dwsize)
747  # alloc_addr = args.lpvoid
748  jitter.vm.add_memory_page(
749  alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize)
750 
751  log.debug('Memory addr: %x', alloc_addr)
752  jitter.func_ret_stdcall(ret_ad, alloc_addr)
753 
754 
756  ret_ad, _ = jitter.func_args_stdcall(["lpvoid", "dwsize", "alloc_type"])
757  jitter.func_ret_stdcall(ret_ad, 0)
758 
759 
761  ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex"])
762  jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw)
763 
764 
766  ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex", "newlong"])
767  jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw)
768 
769 
770 def kernel32_GetModuleFileName(jitter, funcname, set_str):
771  ret_ad, args = jitter.func_args_stdcall(["hmodule", "lpfilename", "nsize"])
772 
773  if args.hmodule in [0, winobjs.hcurmodule]:
774  p = winobjs.module_path[:]
775  elif (winobjs.runtime_dll and
776  args.hmodule in winobjs.runtime_dll.name2off.values()):
777  name_inv = dict([(x[1], x[0])
778  for x in winobjs.runtime_dll.name2off.items()])
779  p = name_inv[args.hmodule]
780  else:
781  log.warning(('Unknown module 0x%x.' +
782  'Set winobjs.hcurmodule and retry'), args.hmodule)
783  p = None
784 
785  if p is None:
786  l = 0
787  elif args.nsize < len(p):
788  p = p[:args.nsize]
789  l = len(p)
790  else:
791  l = len(p)
792 
793  if p:
794  jitter.vm.set_mem(args.lpfilename, set_str(p))
795 
796  jitter.func_ret_stdcall(ret_ad, l)
797 
798 
800  kernel32_GetModuleFileName(jitter, whoami(), set_str_ansi)
801 
802 
804  kernel32_GetModuleFileName(jitter, whoami(), set_str_unic)
805 
806 
807 def kernel32_CreateMutex(jitter, funcname, get_str):
808  ret_ad, args = jitter.func_args_stdcall(["mutexattr", "initowner",
809  "lpname"])
810 
811  if args.lpname:
812  name = get_str(jitter, args.lpname)
813  log.debug(name)
814  else:
815  name = None
816  if args.initowner:
817  if name in winobjs.mutex:
818  raise NotImplementedError("Untested case")
819  # ret = 0
820  else:
821  winobjs.mutex[name] = id(name)
822  ret = winobjs.mutex[name]
823  else:
824  if name in winobjs.mutex:
825  raise NotImplementedError("Untested case")
826  # ret = 0
827  else:
828  winobjs.mutex[name] = id(name)
829  ret = winobjs.mutex[name]
830  jitter.func_ret_stdcall(ret_ad, ret)
831 
832 
834  kernel32_CreateMutex(jitter, whoami(), get_str_ansi)
835 
836 
838  kernel32_CreateMutex(jitter, whoami(), get_str_unic)
839 
840 
842  ret_ad, args = jitter.func_args_stdcall(["hwndowner", "nfolder", "ppidl"])
843  jitter.vm.set_mem(args.ppidl, pck32(args.nfolder))
844  jitter.func_ret_stdcall(ret_ad, 0)
845 
846 
847 def kernel32_SHGetPathFromIDList(jitter, funcname, set_str):
848  ret_ad, args = jitter.func_args_stdcall(["pidl", "ppath"])
849 
850  if args.pidl == 7: # CSIDL_STARTUP:
851  s = "c:\\doc\\user\\startmenu\\programs\\startup"
852  s = set_str(s)
853  else:
854  raise ValueError('pidl not implemented', args.pidl)
855  jitter.vm.set_mem(args.ppath, s)
856  jitter.func_ret_stdcall(ret_ad, 1)
857 
858 
860  kernel32_SHGetPathFromIDList(jitter, whoami(), set_str_unic)
861 
862 
864  kernel32_SHGetPathFromIDList(jitter, whoami(), set_str_ansi)
865 
866 
868  ret_ad, _ = jitter.func_args_stdcall(0)
869  jitter.func_ret_stdcall(ret_ad, winobjs.lastwin32error)
870 
871 
873  ret_ad, args = jitter.func_args_stdcall(["errcode"])
874  # lasterr addr
875  # ad = FS_0_AD + 0x34
876  # jitter.vm.set_mem(ad, pck32(args.errcode))
877  winobjs.lastwin32error = args.errcode
878  jitter.func_ret_stdcall(ret_ad, 0)
879 
880 
882  kernel32_SetLastError(jitter)
883 
884 
886  ret_ad, args = jitter.func_args_stdcall(["dllname"])
887 
888  libname = get_str_ansi(jitter, args.dllname, 0x100)
889  log.info(libname)
890 
891  ret = winobjs.runtime_dll.lib_get_add_base(libname)
892  log.info("ret %x", ret)
893  jitter.func_ret_stdcall(ret_ad, ret)
894 
895 
897  ret_ad, args = jitter.func_args_stdcall(["dllname", "hfile", "flags"])
898 
899  if args.hfile != 0:
900  raise NotImplementedError("Untested case")
901  libname = get_str_ansi(jitter, args.dllname, 0x100)
902  log.info(libname)
903 
904  ret = winobjs.runtime_dll.lib_get_add_base(libname)
905  log.info("ret %x", ret)
906  jitter.func_ret_stdcall(ret_ad, ret)
907 
908 
910  ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"])
911  fname = args.fname
912  if fname < 0x10000:
913  fname = fname
914  else:
915  fname = get_str_ansi(jitter, fname, 0x100)
916  if not fname:
917  fname = None
918  log.info(fname)
919  if fname is not None:
920  ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
921  else:
922  ad = 0
923  ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
924  jitter.add_breakpoint(ad, jitter.handle_lib)
925  jitter.func_ret_stdcall(ret_ad, ad)
926 
927 
929  ret_ad, args = jitter.func_args_stdcall(["dllname"])
930 
931  libname = get_str_unic(jitter, args.dllname, 0x100)
932  log.info(libname)
933 
934  ret = winobjs.runtime_dll.lib_get_add_base(libname)
935  log.info("ret %x", ret)
936  jitter.func_ret_stdcall(ret_ad, ret)
937 
938 
939 def kernel32_GetModuleHandle(jitter, funcname, get_str):
940  ret_ad, args = jitter.func_args_stdcall(["dllname"])
941 
942  if args.dllname:
943  libname = get_str(jitter, args.dllname)
944  log.info(libname)
945  if libname:
946  ret = winobjs.runtime_dll.lib_get_add_base(libname)
947  else:
948  log.warning('unknown module!')
949  ret = 0
950  else:
951  ret = winobjs.current_pe.NThdr.ImageBase
952  log.debug("default img base %x", ret)
953  jitter.func_ret_stdcall(ret_ad, ret)
954 
955 
957  kernel32_GetModuleHandle(jitter, whoami(), get_str_ansi)
958 
959 
961  kernel32_GetModuleHandle(jitter, whoami(), get_str_unic)
962 
963 
965  ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"])
966  jitter.func_ret_stdcall(ret_ad, 1)
967 
968 
970  oemId = 0
971  dwPageSize = 0x1000
972  lpMinimumApplicationAddress = 0x10000
973  lpMaximumApplicationAddress = 0x7ffeffff
974  dwActiveProcessorMask = 0x1
975  numberOfProcessors = 0x1
976  ProcessorsType = 586
977  dwAllocationgranularity = 0x10000
978  wProcessorLevel = 0x6
979  ProcessorRevision = 0xf0b
980 
981  def pack(self):
982  return struct.pack('IIIIIIIIHH',
983  self.oemId,
984  self.dwPageSize,
988  self.numberOfProcessors,
989  self.ProcessorsType,
991  self.wProcessorLevel,
992  self.ProcessorRevision)
993 
994 
996  ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
997  sysinfo = systeminfo()
998  jitter.vm.set_mem(args.sys_ptr, sysinfo.pack())
999  jitter.func_ret_stdcall(ret_ad, 0)
1000 
1001 
1003  ret_ad, args = jitter.func_args_stdcall(["process", "bool_ptr"])
1004  jitter.vm.set_mem(args.bool_ptr, pck32(0))
1005  jitter.func_ret_stdcall(ret_ad, 1)
1006 
1007 
1009  ret_ad, _ = jitter.func_args_stdcall(0)
1010  s = winobjs.module_path + '\x00'
1011  s = '"%s"' % s
1012  alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
1013  jitter.vm.set_mem(alloc_addr, s)
1014  jitter.func_ret_stdcall(ret_ad, alloc_addr)
1015 
1016 
1018  ret_ad, _ = jitter.func_args_stdcall(0)
1019  s = winobjs.module_path + '\x00'
1020  s = set_str_unic('"%s"' % s)
1021  alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
1022  jitter.vm.set_mem(alloc_addr, s)
1023  jitter.func_ret_stdcall(ret_ad, alloc_addr)
1024 
1025 
1027  ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"])
1028  cmd = get_str_unic(jitter, args.pcmd)
1029  log.debug(cmd)
1030  tks = cmd.split(' ')
1031  addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks))
1032  addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1))
1033  o = 0
1034  for i, t in enumerate(tks):
1035  x = set_str_unic(t) + "\x00\x00"
1036  jitter.vm.set_mem(addr_ret + 4 * i, pck32(addr + o))
1037  jitter.vm.set_mem(addr + o, x)
1038  o += len(x) + 2
1039 
1040  jitter.vm.set_mem(addr_ret + 4 * i, pck32(0))
1041  jitter.vm.set_mem(args.pnumargs, pck32(len(tks)))
1042  jitter.func_ret_stdcall(ret_ad, addr_ret)
1043 
1044 
1045 def cryptdll_MD5Init(jitter):
1046  ret_ad, args = jitter.func_args_stdcall(["ad_ctx"])
1047  index = len(winobjs.cryptdll_md5_h)
1048  h = MD5.new()
1049  winobjs.cryptdll_md5_h[index] = h
1050 
1051  jitter.vm.set_mem(args.ad_ctx, pck32(index))
1052  jitter.func_ret_stdcall(ret_ad, 0)
1053 
1054 
1056  ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"])
1057 
1058  index = jitter.vm.get_mem(args.ad_ctx, 4)
1059  index = upck32(index)
1060  if not index in winobjs.cryptdll_md5_h:
1061  raise ValueError('unknown h context', index)
1062 
1063  data = jitter.vm.get_mem(args.ad_input, args.inlen)
1064  winobjs.cryptdll_md5_h[index].update(data)
1065  log.debug(hexdump(data))
1066 
1067  jitter.func_ret_stdcall(ret_ad, 0)
1068 
1069 
1070 def cryptdll_MD5Final(jitter):
1071  ret_ad, args = jitter.func_args_stdcall(["ad_ctx"])
1072 
1073  index = jitter.vm.get_mem(args.ad_ctx, 4)
1074  index = upck32(index)
1075  if not index in winobjs.cryptdll_md5_h:
1076  raise ValueError('unknown h context', index)
1077  h = winobjs.cryptdll_md5_h[index].digest()
1078  jitter.vm.set_mem(args.ad_ctx + 88, h)
1079  jitter.func_ret_stdcall(ret_ad, 0)
1080 
1081 
1083  ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_str"])
1084 
1085  s = get_str_ansi(jitter, args.ad_str)
1086  l = len(s)
1087  jitter.vm.set_mem(args.ad_ctx,
1088  pck16(l) + pck16(l + 1) + pck32(args.ad_str))
1089  jitter.func_ret_stdcall(ret_ad, 0)
1090 
1091 
1093  ret_ad, args = jitter.func_args_stdcall(["ad_ctxu", "case_i", "h_id",
1094  "phout"])
1095 
1096  if args.h_id != 1:
1097  raise ValueError('unk hash unicode', args.h_id)
1098 
1099  l1, l2, ptra = struct.unpack('HHL', jitter.vm.get_mem(args.ad_ctxu, 8))
1100  s = jitter.vm.get_mem(ptra, l1)
1101  s = s[:-1]
1102  hv = 0
1103 
1104  if args.case_i:
1105  s = s.lower()
1106  for c in s:
1107  hv = ((65599 * hv) + ord(c)) & 0xffffffff
1108  jitter.vm.set_mem(args.phout, pck32(hv))
1109  jitter.func_ret_stdcall(ret_ad, 0)
1110 
1111 
1113  ret_ad, args = jitter.func_args_stdcall(["ad_dst", "ad_src", "m_len"])
1114  data = jitter.vm.get_mem(args.ad_src, args.m_len)
1115  jitter.vm.set_mem(args.ad_dst, data)
1116  jitter.func_ret_stdcall(ret_ad, 0)
1117 
1118 
1120  ret_ad, args = jitter.func_args_stdcall(['ad_ad_ch'])
1121  ad_ch = upck32(jitter.vm.get_mem(args.ad_ad_ch, 4))
1122  ch = ord(jitter.vm.get_mem(ad_ch, 1))
1123  jitter.vm.set_mem(args.ad_ad_ch, pck32(ad_ch + 1))
1124  jitter.func_ret_stdcall(ret_ad, ch)
1125 
1126 
1128  ret_ad, args = jitter.func_args_stdcall(["flags", "main_str_ad",
1129  "search_chars_ad", "pos_ad"])
1130 
1131  if args.flags != 0:
1132  raise ValueError('unk flags')
1133 
1134  ml1, ml2, mptra = struct.unpack('HHL',
1135  jitter.vm.get_mem(args.main_str_ad, 8))
1136  sl1, sl2, sptra = struct.unpack(
1137  'HHL', jitter.vm.get_mem(args.search_chars_ad, 8))
1138  main_data = jitter.vm.get_mem(mptra, ml1)[:-1]
1139  search_data = jitter.vm.get_mem(sptra, sl1)[:-1]
1140 
1141  pos = None
1142  for i, c in enumerate(main_data):
1143  for s in search_data:
1144  if s == c:
1145  pos = i
1146  break
1147  if pos:
1148  break
1149  if pos is None:
1150  ret = 0xC0000225
1151  jitter.vm.set_mem(args.pos_ad, pck32(0))
1152  else:
1153  ret = 0
1154  jitter.vm.set_mem(args.pos_ad, pck32(pos))
1155 
1156  jitter.func_ret_stdcall(ret_ad, ret)
1157 
1158 
1160  ret_ad, args = jitter.func_args_stdcall(["dwinit", "pdata", "ilen"])
1161  data = jitter.vm.get_mem(args.pdata, args.ilen)
1162  crc_r = crc32(data, args.dwinit)
1163  jitter.func_ret_stdcall(ret_ad, crc_r)
1164 
1165 
1167  ret_ad, args = jitter.func_args_stdcall(['multiplicand_low',
1168  'multiplicand_high',
1169  'multiplier'])
1170  a = (args.multiplicand_high << 32) + args.multiplicand_low
1171  a = a * args.multiplier
1172  jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
1173 
1174 
1176  ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high',
1177  'b_low', 'b_high'])
1178  a = (args.a_high << 32) + args.a_low + (args.b_high << 32) + args.b_low
1179  jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
1180 
1181 
1183  ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', 's_count'])
1184  a = ((args.a_high << 32) + args.a_low) >> args.s_count
1185  jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
1186 
1187 
1189  ret_ad, args = jitter.func_args_stdcall(['a', 'b'])
1190  a = args.a * args.b
1191  jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
1192 
1193 
1195  ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high',
1196  'b_low', 'b_high'])
1197  a = (args.a_high << 32) + args.a_low - (args.b_high << 32) + args.b_low
1198  jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
1199 
1200 
1202  ret_ad, args = jitter.func_args_stdcall(['ad1', 'ad2', 'm_len'])
1203  data1 = jitter.vm.get_mem(args.ad1, args.m_len)
1204  data2 = jitter.vm.get_mem(args.ad2, args.m_len)
1205 
1206  i = 0
1207  while data1[i] == data2[i]:
1208  i += 1
1209  if i >= args.m_len:
1210  break
1211 
1212  jitter.func_ret_stdcall(ret_ad, i)
1213 
1214 
1216  ret_ad, _ = jitter.func_args_stdcall(0)
1217  jitter.func_ret_stdcall(ret_ad, 0x00110022)
1218 
1219 
1220 def kernel32_Sleep(jitter):
1221  ret_ad, _ = jitter.func_args_stdcall(['t'])
1222  jitter.func_ret_stdcall(ret_ad, 0)
1223 
1224 
1226  ret_ad, _ = jitter.func_args_stdcall(['h', 'ad'])
1227  jitter.func_ret_stdcall(ret_ad, 0)
1228 
1229 
1231  ret_ad, _ = jitter.func_args_stdcall(['lp', 'ucb'])
1232  jitter.func_ret_stdcall(ret_ad, 0)
1233 
1234 
1236  ret_ad, args = jitter.func_args_stdcall(['my_event', 'my_type',
1237  'my_state'])
1238  jitter.vm.set_mem(args.my_event, pck32(winobjs.win_event_num))
1239  winobjs.win_event_num += 1
1240 
1241  jitter.func_ret_stdcall(ret_ad, 0)
1242 
1243 
1245  ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
1246 
1247  s = struct.pack("IIIII",
1248  0x114, # struct size
1249  0x5, # maj vers
1250  0x2, # min vers
1251  0x666, # build nbr
1252  0x2, # platform id
1253  ) + set_str_unic("Service pack 4")
1254 
1255  jitter.vm.set_mem(args.ptr_version, s)
1256  jitter.func_ret_stdcall(ret_ad, 0)
1257 
1258 
1260  ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
1261 
1262  s = jitter.vm.get_mem(args.ptr_version, 0x5 * 4)
1263  s_size, s_majv, s_minv, s_buildn, s_platform = struct.unpack('IIIII', s)
1264  raise NotImplementedError("Untested case")
1265  # jitter.vm.set_mem(args.ptr_version, s)
1266  # jitter.func_ret_stdcall(ret_ad, 0)
1267 
1268 
1270  ret_ad, _ = jitter.func_args_stdcall(0)
1271  jitter.func_ret_stdcall(ret_ad, 0)
1272 
1273 
1274 def mdl2ad(n):
1275  return winobjs.nt_mdl_ad + 0x10 * n
1276 
1277 
1278 def ad2mdl(ad):
1279  return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFFL) / 0x10
1280 
1281 
1283  ret_ad, args = jitter.func_args_stdcall(["v_addr", "l", "second_buf",
1284  "chargequota", "pirp"])
1285  m = mdl(args.v_addr, args.l)
1286  winobjs.nt_mdl[winobjs.nt_mdl_cur] = m
1287  jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), str(m))
1288  jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur))
1289  winobjs.nt_mdl_cur += 1
1290 
1291 
1293  ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode", "op"])
1294 
1295  if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
1296  raise ValueError('unk mdl', hex(args.p_mdl))
1297  jitter.func_ret_stdcall(ret_ad, 0)
1298 
1299 
1301  ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode",
1302  "cache_type", "base_ad",
1303  "bugcheckonfailure",
1304  "priority"])
1305  if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
1306  raise ValueError('unk mdl', hex(args.p_mdl))
1307 
1308  jitter.func_ret_stdcall(ret_ad, winobjs.nt_mdl[ad2mdl(args.p_mdl)].ad)
1309 
1310 
1312  ret_ad, args = jitter.func_args_stdcall(["p_mdl", "prot"])
1313  if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
1314  raise ValueError('unk mdl', hex(args.p_mdl))
1315 
1316  jitter.func_ret_stdcall(ret_ad, 0)
1317 
1318 
1320  ret_ad, args = jitter.func_args_stdcall(['p_mdl'])
1321  if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
1322  raise ValueError('unk mdl', hex(args.p_mdl))
1323 
1324  jitter.func_ret_stdcall(ret_ad, 0)
1325 
1326 
1328  ret_ad, args = jitter.func_args_stdcall(['p_mdl'])
1329  if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
1330  raise ValueError('unk mdl', hex(args.p_mdl))
1331  del(winobjs.nt_mdl[ad2mdl(args.p_mdl)])
1332  jitter.func_ret_stdcall(ret_ad, 0)
1333 
1334 
1336  ret_ad, _ = jitter.func_args_stdcall(0)
1337  jitter.func_ret_stdcall(ret_ad, 0)
1338 
1339 
1341  ret_ad, args = jitter.func_args_stdcall(["relativeto", "path",
1342  "querytable",
1343  "context",
1344  "environ"])
1345  # path = get_str_unic(jitter, args.path)
1346  jitter.func_ret_stdcall(ret_ad, 0)
1347 
1348 
1350  ret_ad, args = jitter.func_args_stdcall(["pool_type",
1351  "nbr_of_bytes",
1352  "tag", "priority"])
1353  alloc_addr = winobjs.heap.next_addr(args.nbr_of_bytes)
1354  jitter.vm.add_memory_page(
1355  alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * args.nbr_of_bytes)
1356 
1357  jitter.func_ret_stdcall(ret_ad, alloc_addr)
1358 
1359 
1360 def my_lstrcmp(jitter, funcname, get_str):
1361  ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
1362  s1 = get_str(args.ptr_str1)
1363  s2 = get_str(args.ptr_str2)
1364  jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
1365 
1366 
1367 def kernel32_lstrcmpA(jitter):
1368  my_lstrcmp(jitter, whoami(), lambda x: get_str_ansi(jitter, x))
1369 
1370 
1372  my_lstrcmp(jitter, whoami(), lambda x: get_str_ansi(jitter, x).lower())
1373 
1374 
1375 def kernel32_lstrcmpW(jitter):
1376  my_lstrcmp(jitter, whoami(), lambda x: get_str_unic(jitter, x))
1377 
1378 
1380  my_lstrcmp(jitter, whoami(), lambda x: get_str_unic(jitter, x).lower())
1381 
1382 
1383 def kernel32_lstrcmpi(jitter):
1384  my_lstrcmp(jitter, whoami(), lambda x: get_str_ansi(jitter, x).lower())
1385 
1386 
1387 def my_strcpy(jitter, funcname, get_str, set_str):
1388  ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
1389  s2 = get_str(jitter, args.ptr_str2)
1390  jitter.vm.set_mem(args.ptr_str1, set_str(s2))
1391  jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
1392 
1393 
1394 def kernel32_lstrcpyW(jitter):
1395  my_strcpy(jitter, whoami(), get_str_unic,
1396  lambda x: set_str_unic(x) + "\x00\x00")
1397 
1398 
1399 def kernel32_lstrcpyA(jitter):
1400  my_strcpy(jitter, whoami(), get_str_ansi, lambda x: x + "\x00")
1401 
1402 
1403 def kernel32_lstrcpy(jitter):
1404  my_strcpy(jitter, whoami(), get_str_ansi, lambda x: x + "\x00")
1405 
1406 
1407 def kernel32_lstrcpyn(jitter):
1408  ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
1409  "mlen"])
1410  s2 = get_str_ansi(jitter, args.ptr_str2)
1411  s2 = s2[:args.mlen]
1412  jitter.vm.set_mem(args.ptr_str1, s2)
1413  jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
1414 
1415 
1416 def my_strlen(jitter, funcname, get_str, mylen):
1417  ret_ad, args = jitter.func_args_stdcall(["src"])
1418  src = get_str(jitter, args.src)
1419  jitter.func_ret_stdcall(ret_ad, mylen(src))
1420 
1421 
1422 def kernel32_lstrlenA(jitter):
1423  my_strlen(jitter, whoami(), get_str_ansi, len)
1424 
1425 
1426 def kernel32_lstrlenW(jitter):
1427  my_strlen(jitter, whoami(), get_str_unic, len)
1428 
1429 
1430 def kernel32_lstrlen(jitter):
1431  my_strlen(jitter, whoami(), get_str_ansi, len)
1432 
1433 
1434 def my_lstrcat(jitter, funcname, get_str):
1435  ret_ad, args = jitter.func_args_stdcall(['ptr_str1', 'ptr_str2'])
1436  s1 = get_str(jitter, args.ptr_str1)
1437  s2 = get_str(jitter, args.ptr_str2)
1438  jitter.vm.set_mem(args.ptr_str1, s1 + s2)
1439  jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
1440 
1441 
1442 def kernel32_lstrcatA(jitter):
1443  my_lstrcat(jitter, whoami(), get_str_ansi)
1444 
1445 
1446 def kernel32_lstrcatW(jitter):
1447  my_lstrcat(jitter, whoami(), get_str_unic)
1448 
1449 
1451  ret_ad, args = jitter.func_args_stdcall(["geoclass"])
1452  if args.geoclass == 14:
1453  ret = 12345678
1454  elif args.geoclass == 16:
1455  ret = 55667788
1456  else:
1457  raise ValueError('unknown geolcass')
1458  jitter.func_ret_stdcall(ret_ad, ret)
1459 
1460 
1461 def my_GetVolumeInformation(jitter, funcname, get_str, set_str):
1462  ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
1463  "lpvolumenamebuffer",
1464  "nvolumenamesize",
1465  "lpvolumeserialnumber",
1466  "lpmaximumcomponentlength",
1467  "lpfilesystemflags",
1468  "lpfilesystemnamebuffer",
1469  "nfilesystemnamesize"])
1470  if args.lprootpathname:
1471  s = get_str(jitter, args.lprootpathname)
1472 
1473  if args.lpvolumenamebuffer:
1474  s = "volumename"
1475  s = s[:args.nvolumenamesize]
1476  jitter.vm.set_mem(args.lpvolumenamebuffer, set_str(s))
1477 
1478  if args.lpvolumeserialnumber:
1479  jitter.vm.set_mem(args.lpvolumeserialnumber, pck32(11111111))
1480  if args.lpmaximumcomponentlength:
1481  jitter.vm.set_mem(args.lpmaximumcomponentlength, pck32(0xff))
1482  if args.lpfilesystemflags:
1483  jitter.vm.set_mem(args.lpfilesystemflags, pck32(22222222))
1484 
1485  if args.lpfilesystemnamebuffer:
1486  s = "filesystemname"
1487  s = s[:args.nfilesystemnamesize]
1488  jitter.vm.set_mem(args.lpfilesystemnamebuffer, set_str(s))
1489 
1490  jitter.func_ret_stdcall(ret_ad, 1)
1491 
1492 
1495  jitter, whoami(), get_str_ansi, lambda x: x + "\x00")
1496 
1497 
1499  my_GetVolumeInformation(jitter, whoami(), get_str_unic, set_str_unic)
1500 
1501 
1503  ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags",
1504  "lpmultibytestr",
1505  "cbmultibyte",
1506  "lpwidecharstr",
1507  "cchwidechar"])
1508  src = get_str_ansi(jitter, args.lpmultibytestr) + '\x00'
1509  l = len(src)
1510 
1511  src = "\x00".join(list(src))
1512  jitter.vm.set_mem(args.lpwidecharstr, src)
1513  jitter.func_ret_stdcall(ret_ad, l)
1514 
1515 
1516 def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
1517  ret_ad, args = jitter.func_args_stdcall(["lpname", "lpbuffer",
1518  "nsize"])
1519 
1520  s = get_str(jitter, args.lpname)
1521  if get_str == get_str_unic:
1522  s = s
1523  log.debug('variable %r', s)
1524  if s in winobjs.env_variables:
1525  v = set_str(winobjs.env_variables[s])
1526  else:
1527  log.warning('WARNING unknown env variable %r', s)
1528  v = ""
1529  jitter.vm.set_mem(args.lpbuffer, v)
1530  jitter.func_ret_stdcall(ret_ad, mylen(v))
1531 
1532 
1533 def my_GetSystemDirectory(jitter, funcname, set_str):
1534  ret_ad, args = jitter.func_args_stdcall(["lpbuffer", "usize"])
1535  s = "c:\\windows\\system32"
1536  l = len(s)
1537  s = set_str(s)
1538  jitter.vm.set_mem(args.lpbuffer, s)
1539  jitter.func_ret_stdcall(ret_ad, l)
1540 
1541 
1543  my_GetSystemDirectory(jitter, whoami(), set_str_ansi)
1544 
1545 
1547  my_GetSystemDirectory(jitter, whoami(), set_str_unic)
1548 
1549 
1550 def my_CreateDirectory(jitter, funcname, get_str):
1551  ret_ad, args = jitter.func_args_stdcall(['lppath', 'secattrib'])
1552  # path = get_str(jitter, args.lppath)
1553  jitter.func_ret_stdcall(ret_ad, 0x1337)
1554 
1555 
1557  my_CreateDirectory(jitter, whoami(), get_str_unic)
1558 
1559 
1561  my_CreateDirectory(jitter, whoami(), get_str_ansi)
1562 
1563 
1566  get_str_ansi,
1567  lambda x: x + "\x00",
1568  len)
1569 
1570 
1573  get_str_unic,
1574  lambda x: "\x00".join(list(x + "\x00")),
1575  len)
1576 
1577 
1578 def my_CreateEvent(jitter, funcname, get_str):
1579  ret_ad, args = jitter.func_args_stdcall(["lpeventattributes",
1580  "bmanualreset",
1581  "binitialstate",
1582  "lpname"])
1583  s = get_str(jitter, args.lpname) if args.lpname else None
1584  if not s in winobjs.events_pool:
1585  winobjs.events_pool[s] = (args.bmanualreset, args.binitialstate)
1586  else:
1587  log.warning('WARNING: known event')
1588  jitter.func_ret_stdcall(ret_ad, id(s))
1589 
1590 
1592  my_CreateEvent(jitter, whoami(), get_str_ansi)
1593 
1594 
1596  my_CreateEvent(jitter, whoami(), get_str_unic)
1597 
1598 
1600  ret_ad, args = jitter.func_args_stdcall(['handle', 'dwms'])
1601 
1602  t_start = time.time() * 1000
1603  found = False
1604  while True:
1605  if args.dwms and args.dwms + t_start > time.time() * 1000:
1606  ret = 0x102
1607  break
1608  for key, value in winobjs.events_pool.iteritems():
1609  if key != args.handle:
1610  continue
1611  found = True
1612  if value[1] == 1:
1613  ret = 0
1614  break
1615  if not found:
1616  log.warning('unknown handle')
1617  ret = 0xffffffff
1618  break
1619  time.sleep(0.1)
1620  jitter.func_ret_stdcall(ret_ad, ret)
1621 
1622 
1624  ret_ad, args = jitter.func_args_stdcall(["lpfilename",
1625  "dwfileattributes"])
1626  if args.lpfilename:
1627  # fname = get_str_ansi(jitter, args.lpfilename)
1628  ret = 1
1629  else:
1630  ret = 0
1631  jitter.vm.set_mem(FS_0_AD + 0x34, pck32(3))
1632 
1633  jitter.func_ret_stdcall(ret_ad, ret)
1634 
1635 
1637  ret_ad, args = jitter.func_args_stdcall(["dst", "src", "l"])
1638  s = jitter.vm.get_mem(args.src, args.l)
1639  jitter.vm.set_mem(args.dst, s)
1640  jitter.func_ret_stdcall(ret_ad, 1)
1641 
1642 
1644  ret_ad, args = jitter.func_args_stdcall(["systeminformationclass",
1645  "systeminformation",
1646  "systeminformationl",
1647  "returnl"])
1648  if args.systeminformationclass == 2:
1649  # SYSTEM_PERFORMANCE_INFORMATION
1650  o = struct.pack('II', 0x22222222, 0x33333333)
1651  o += "\x00" * args.systeminformationl
1652  o = o[:args.systeminformationl]
1653  jitter.vm.set_mem(args.systeminformation, o)
1654  else:
1655  raise ValueError('unknown sysinfo class',
1656  args.systeminformationclass)
1657  jitter.func_ret_stdcall(ret_ad, 0)
1658 
1659 
1661  ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
1662  "pdwsize",
1663  "flnewprotect",
1664  "lpfloldprotect"])
1665 
1666  ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
1667  # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
1668  # XXX mask hpart
1669  flnewprotect = args.flnewprotect & 0xFFF
1670 
1671  if not flnewprotect in access_dict:
1672  raise ValueError('unknown access dw!')
1673  jitter.vm.set_mem_access(ad, access_dict[flnewprotect])
1674 
1675  # XXX todo real old protect
1676  jitter.vm.set_mem(args.lpfloldprotect, pck32(0x40))
1677 
1678  jitter.func_ret_stdcall(ret_ad, 1)
1679 
1680 
1682  ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
1683  "zerobits", "pdwsize",
1684  "alloc_type",
1685  "flprotect"])
1686 
1687  # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
1688  dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
1689 
1690  access_dict = {
1691  0x0: 0,
1692  0x1: 0,
1693  0x2: PAGE_READ,
1694  0x4: PAGE_READ | PAGE_WRITE,
1695  0x10: PAGE_EXEC,
1696  0x20: PAGE_EXEC | PAGE_READ,
1697  0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
1698  0x100: 0,
1699  }
1700 
1701  # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
1702 
1703  if not args.flprotect in access_dict:
1704  raise ValueError('unknown access dw!')
1705 
1706  alloc_addr = winobjs.heap.next_addr(dwsize)
1707  jitter.vm.add_memory_page(
1708  alloc_addr, access_dict[args.flprotect], "\x00" * dwsize)
1709  jitter.vm.set_mem(args.lppvoid, pck32(alloc_addr))
1710 
1711  jitter.func_ret_stdcall(ret_ad, 0)
1712 
1713 
1715  ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
1716  "pdwsize", "alloc_type"])
1717  # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
1718  # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
1719  jitter.func_ret_stdcall(ret_ad, 0)
1720 
1721 
1723  ret_ad, args = jitter.func_args_stdcall(["pstring", "source"])
1724  s = get_str_ansi(jitter, args.source)
1725  l = len(s) + 1
1726  o = struct.pack('HHI', l, l, args.source)
1727  jitter.vm.set_mem(args.pstring, o)
1728  jitter.func_ret_stdcall(ret_ad, 0)
1729 
1730 
1732  ret_ad, args = jitter.func_args_stdcall(["dst", "src", "alloc_str"])
1733 
1734  l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
1735  s = get_str_ansi(jitter, p_src)
1736  s = ("\x00".join(s + "\x00"))
1737  l = len(s) + 1
1738  if args.alloc_str:
1739  alloc_addr = winobjs.heap.next_addr(l)
1740  jitter.vm.add_memory_page(
1741  alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * l)
1742  else:
1743  alloc_addr = p_src
1744  jitter.vm.set_mem(alloc_addr, s)
1745  o = struct.pack('HHI', l, l, alloc_addr)
1746  jitter.vm.set_mem(args.dst, o)
1747  jitter.func_ret_stdcall(ret_ad, 0)
1748 
1749 
1750 def ntdll_LdrLoadDll(jitter):
1751  ret_ad, args = jitter.func_args_stdcall(["path", "flags",
1752  "modname", "modhandle"])
1753 
1754  l1, l2, p_src = struct.unpack('HHI',
1755  jitter.vm.get_mem(args.modname, 0x8))
1756  s = get_str_unic(jitter, p_src)
1757  libname = s.lower()
1758 
1759  ad = winobjs.runtime_dll.lib_get_add_base(libname)
1760  jitter.vm.set_mem(args.modhandle, pck32(ad))
1761 
1762  jitter.func_ret_stdcall(ret_ad, 0)
1763 
1764 
1766  ret_ad, args = jitter.func_args_stdcall(['src'])
1767  # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
1768  # s = get_str_unic(jitter, p_src)
1769  jitter.func_ret_stdcall(ret_ad, 0)
1770 
1771 
1773  ret_ad, args = jitter.func_args_stdcall(["libbase", "pfname",
1774  "opt", "p_ad"])
1775 
1776  l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8))
1777  fname = get_str_ansi(jitter, p_src)
1778 
1779  ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
1780 
1781  jitter.vm.set_mem(args.p_ad, pck32(ad))
1782 
1783  jitter.func_ret_stdcall(ret_ad, 0)
1784 
1785 
1786 def ntdll_memset(jitter):
1787  ret_ad, args = jitter.func_args_stdcall(['addr', 'c', 'size'])
1788  jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
1789  jitter.func_ret_stdcall(ret_ad, args.addr)
1790 
1791 
1792 def msvcrt_memset(jitter):
1793  ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
1794  jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
1795  jitter.func_ret_cdecl(ret_ad, args.addr)
1796 
1797 
1798 def msvcrt_memcpy(jitter):
1799  ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size'])
1800  s = jitter.vm.get_mem(args.src, args.size)
1801  jitter.vm.set_mem(args.dst, s)
1802  jitter.func_ret_cdecl(ret_ad, args.dst)
1803 
1804 
1805 def msvcrt_memcmp(jitter):
1806  ret_ad, args = jitter.func_args_cdecl(['ps1', 'ps2', 'size'])
1807  s1 = jitter.vm.get_mem(args.ps1, args.size)
1808  s2 = jitter.vm.get_mem(args.ps2, args.size)
1809  ret = cmp(s1, s2)
1810  jitter.func_ret_cdecl(ret_ad, ret)
1811 
1812 
1814  ret_ad, args = jitter.func_args_stdcall(['path_ad'])
1815  path = get_str_ansi(jitter, args.path_ad)
1816  i = path.rfind('.')
1817  if i == -1:
1818  i = args.path_ad + len(path)
1819  else:
1820  i = args.path_ad + i
1821  jitter.func_ret_stdcall(ret_ad, i)
1822 
1823 
1825  ret_ad, args = jitter.func_args_stdcall(['path_ad'])
1826  path = get_str_unic(jitter, args.path_ad)
1827  i = path.rfind('\\')
1828  if i == -1:
1829  i = 0
1830  jitter.vm.set_mem(args.path_ad + i * 2, "\x00\x00")
1831  path = get_str_unic(jitter, args.path_ad)
1832  jitter.func_ret_stdcall(ret_ad, 1)
1833 
1834 
1836  ret_ad, args = jitter.func_args_stdcall(['ptr_prefix', 'ptr_path'])
1837  prefix = get_str_unic(jitter, args.ptr_prefix)
1838  path = get_str_unic(jitter, args.ptr_path)
1839 
1840  if path.startswith(prefix):
1841  ret = 1
1842  else:
1843  ret = 0
1844  jitter.func_ret_stdcall(ret_ad, ret)
1845 
1846 
1848  ret_ad, args = jitter.func_args_stdcall(['ptr_path'])
1849  fname = get_str_unic(jitter, args.ptr_path)
1850 
1851  sb_fname = windows_to_sbpath(fname)
1852 
1853  s = os.stat(sb_fname)
1854  ret = 0
1855  if stat.S_ISDIR(s.st_mode):
1856  ret = 1
1857 
1858  jitter.func_ret_cdecl(ret_ad, ret)
1859 
1860 
1861 def shlwapi_PathIsFileSpec(jitter, funcname, get_str):
1862  ret_ad, args = jitter.func_args_stdcall(['path_ad'])
1863  path = get_str(jitter, args.path_ad)
1864  if path.find(':') != -1 and path.find('\\') != -1:
1865  ret = 0
1866  else:
1867  ret = 1
1868 
1869  jitter.func_ret_stdcall(ret_ad, ret)
1870 
1871 
1872 def shlwapi_PathGetDriveNumber(jitter, funcname, get_str):
1873  ret_ad, args = jitter.func_args_stdcall(['path_ad'])
1874  path = get_str(jitter, args.path_ad)
1875  l = ord(path[0].upper()) - ord('A')
1876  if 0 <= l <= 25:
1877  ret = l
1878  else:
1879  ret = -1
1880 
1881  jitter.func_ret_stdcall(ret_ad, ret)
1882 
1883 
1885  shlwapi_PathGetDriveNumber(jitter, whoami(), get_str_ansi)
1886 
1887 
1889  shlwapi_PathGetDriveNumber(jitter, whoami(), get_str_unic)
1890 
1891 
1893  shlwapi_PathIsFileSpec(jitter, whoami(), get_str_ansi)
1894 
1895 
1897  shlwapi_PathIsFileSpec(jitter, whoami(), get_str_unic)
1898 
1899 
1900 def shlwapi_StrToIntA(jitter):
1901  ret_ad, args = jitter.func_args_stdcall(['i_str_ad'])
1902  i_str = get_str_ansi(jitter, args.i_str_ad)
1903  try:
1904  i = int(i_str)
1905  except:
1906  log.warning('WARNING cannot convert int')
1907  i = 0
1908 
1909  jitter.func_ret_stdcall(ret_ad, i)
1910 
1911 
1912 def shlwapi_StrToInt64Ex(jitter, funcname, get_str):
1913  ret_ad, args = jitter.func_args_stdcall(['pstr', 'flags', 'pret'])
1914  i_str = get_str(jitter, args.pstr)
1915  if get_str is get_str_unic:
1916  i_str = i_str
1917 
1918  if args.flags == 0:
1919  r = int(i_str)
1920  elif args.flags == 1:
1921  r = int(i_str, 16)
1922  else:
1923  raise ValueError('cannot decode int')
1924 
1925  jitter.vm.set_mem(args.pret, struct.pack('q', r))
1926  jitter.func_ret_stdcall(ret_ad, 1)
1927 
1928 
1930  shlwapi_StrToInt64Ex(jitter, whoami(), get_str_ansi)
1931 
1932 
1934  shlwapi_StrToInt64Ex(jitter, whoami(), get_str_unic)
1935 
1936 
1937 def user32_IsCharAlpha(jitter, funcname, get_str):
1938  ret_ad, args = jitter.func_args_stdcall(["c"])
1939  try:
1940  c = chr(args.c)
1941  except:
1942  log.error('bad char %r', args.c)
1943  c = "\x00"
1944  if c.isalpha(jitter):
1945  ret = 1
1946  else:
1947  ret = 0
1948  jitter.func_ret_stdcall(ret_ad, ret)
1949 
1950 
1952  user32_IsCharAlpha(jitter, whoami(), get_str_ansi)
1953 
1954 
1956  user32_IsCharAlpha(jitter, whoami(), get_str_unic)
1957 
1958 
1960  ret_ad, args = jitter.func_args_stdcall(["c"])
1961  c = chr(args.c)
1962  if c.isalnum(jitter):
1963  ret = 1
1964  else:
1965  ret = 0
1966  jitter.func_ret_stdcall(ret_ad, ret)
1967 
1968 
1969 def shlwapi_StrCmpNIA(jitter):
1970  ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
1971  "nchar"])
1972  s1 = get_str_ansi(jitter, args.ptr_str1).lower()
1973  s2 = get_str_ansi(jitter, args.ptr_str2).lower()
1974  s1 = s1[:args.nchar]
1975  s2 = s2[:args.nchar]
1976  jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
1977 
1978 
1979 def advapi32_RegOpenKeyEx(jitter, funcname, get_str):
1980  ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey",
1981  "reserved", "access",
1982  "phandle"])
1983  s_subkey = get_str(jitter, args.subkey).lower() if args.subkey else ""
1984 
1985  ret_hkey = 0
1986  ret = 2
1987  if args.hkey in winobjs.hkey_handles:
1988  if s_subkey:
1989  h = hash(s_subkey) & 0xffffffff
1990  if h in winobjs.hkey_handles:
1991  ret_hkey = h
1992  ret = 0
1993  else:
1994  log.error('unknown skey')
1995 
1996  jitter.vm.set_mem(args.phandle, pck32(ret_hkey))
1997 
1998  jitter.func_ret_stdcall(ret_ad, ret)
1999 
2000 
2002  advapi32_RegOpenKeyEx(jitter, whoami(), get_str_ansi)
2003 
2004 
2006  advapi32_RegOpenKeyEx(jitter, whoami(), get_str_unic)
2007 
2008 
2009 def advapi32_RegSetValue(jitter, funcname, get_str):
2010  ret_ad, args = jitter.func_args_stdcall(["hkey", "psubkey",
2011  "valuetype", "pvalue",
2012  "vlen"])
2013  # subkey = get_str(jitter, args.psubkey).lower() if args.psubkey else ""
2014  # value = jitter.vm.get_mem(args.pvalue, args.vlen) if args.pvalue else None
2015  jitter.func_ret_stdcall(ret_ad, 0)
2016 
2017 
2019  advapi32_RegSetValue(jitter, whoami(), get_str_ansi)
2020 
2021 
2023  advapi32_RegSetValue(jitter, whoami(), get_str_unic)
2024 
2025 
2027  ret_ad, _ = jitter.func_args_stdcall(0)
2028  jitter.func_ret_stdcall(ret_ad, 0x40c)
2029 
2030 
2031 def kernel32_GetLocaleInfo(jitter, funcname, set_str):
2032  ret_ad, args = jitter.func_args_stdcall(["localeid", "lctype",
2033  "lplcdata", "cchdata"])
2034 
2035  buf = None
2036  ret = 0
2037  if args.localeid == 0x40c:
2038  if args.lctype == 0x3:
2039  buf = "ENGLISH"
2040  buf = buf[:args.cchdata - 1]
2041  jitter.vm.set_mem(args.lplcdata, set_str(buf))
2042  ret = len(buf)
2043  else:
2044  raise ValueError('unimpl localeid')
2045 
2046  jitter.func_ret_stdcall(ret_ad, ret)
2047 
2048 
2050  kernel32_GetLocaleInfo(jitter, whoami(), set_str_ansi)
2051 
2052 
2054  kernel32_GetLocaleInfo(jitter, whoami(), set_str_unic)
2055 
2056 
2057 def kernel32_TlsAlloc(jitter):
2058  ret_ad, _ = jitter.func_args_stdcall(0)
2059  winobjs.tls_index += 1
2060  jitter.func_ret_stdcall(ret_ad, winobjs.tls_index)
2061 
2062 
2063 def kernel32_TlsFree(jitter):
2064  ret_ad, _ = jitter.func_args_stdcall(["tlsindex"])
2065  jitter.func_ret_stdcall(ret_ad, 0)
2066 
2067 
2069  ret_ad, args = jitter.func_args_stdcall(["tlsindex", "tlsvalue"])
2070  winobjs.tls_values[args.tlsindex] = args.tlsvalue
2071  jitter.func_ret_stdcall(ret_ad, 1)
2072 
2073 
2075  ret_ad, args = jitter.func_args_stdcall(["tlsindex"])
2076  if not args.tlsindex in winobjs.tls_values:
2077  raise ValueError("unknown tls val", repr(args.tlsindex))
2078  jitter.func_ret_stdcall(ret_ad, winobjs.tls_values[args.tlsindex])
2079 
2080 
2082  ret_ad, args = jitter.func_args_stdcall(["typeflag"])
2083 
2084  ret = 0
2085  if args.typeflag == 0:
2086  ret = 4
2087  else:
2088  raise ValueError('unimpl keyboard type')
2089 
2090  jitter.func_ret_stdcall(ret_ad, ret)
2091 
2092 
2093 def kernel32_GetStartupInfo(jitter, funcname, set_str):
2094  ret_ad, args = jitter.func_args_stdcall(["ptr"])
2095 
2096  s = "\x00" * 0x2c + "\x81\x00\x00\x00" + "\x0a"
2097 
2098  jitter.vm.set_mem(args.ptr, s)
2099  jitter.func_ret_stdcall(ret_ad, args.ptr)
2100 
2101 
2103  kernel32_GetStartupInfo(jitter, whoami(), set_str_ansi)
2104 
2105 
2107  kernel32_GetStartupInfo(jitter, whoami(), set_str_unic)
2108 
2109 
2111  ret_ad, _ = jitter.func_args_stdcall(0)
2112  jitter.func_ret_stdcall(ret_ad, 0x113377)
2113 
2114 
2116  ret_ad, _ = jitter.func_args_stdcall(["lpcritic"])
2117  jitter.func_ret_stdcall(ret_ad, 0)
2118 
2119 
2121  ret_ad, args = jitter.func_args_stdcall(["nindex"])
2122 
2123  ret = 0
2124  if args.nindex in [0x2a, 0x4a]:
2125  ret = 0
2126  else:
2127  raise ValueError('unimpl index')
2128  jitter.func_ret_stdcall(ret_ad, ret)
2129 
2130 
2132  ret_ad, args = jitter.func_args_stdcall(["version, pwsadata"])
2133  jitter.vm.set_mem(args.pwsadata, "\x01\x01\x02\x02WinSock 2.0\x00")
2134  jitter.func_ret_stdcall(ret_ad, 0)
2135 
2136 
2138  ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
2139 
2140  s = struct.pack('HHHHHHHH',
2141  2011, # year
2142  10, # month
2143  5, # dayofweek
2144  7, # day
2145  13, # hour
2146  37, # minutes
2147  00, # seconds
2148  999, # millisec
2149  )
2150  jitter.vm.set_mem(args.lpsystemtime, s)
2151  jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
2152 
2153 
2155  ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
2156 
2157  s = struct.pack('HHHHHHHH',
2158  2011, # year
2159  10, # month
2160  5, # dayofweek
2161  7, # day
2162  13, # hour
2163  37, # minutes
2164  00, # seconds
2165  999, # millisec
2166  )
2167  jitter.vm.set_mem(args.lpsystemtime, s)
2168  jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
2169 
2170 
2171 def kernel32_CreateFileMapping(jitter, funcname, get_str):
2172  ret_ad, args = jitter.func_args_stdcall(["hfile", "lpattr", "flprotect",
2173  "dwmaximumsizehigh",
2174  "dwmaximumsizelow", "lpname"])
2175  # f = get_str(jitter, args.lpname) if args.lpname else None
2176 
2177  if args.hfile == 0xffffffff:
2178  # Create null mapping
2179  if args.dwmaximumsizehigh:
2180  raise NotImplementedError("Untested case")
2181  hmap = StringIO("\x00"*args.dwmaximumsizelow)
2182  hmap_handle = winobjs.handle_pool.add('filemem', hmap)
2183 
2184  ret = winobjs.handle_pool.add('filemapping', hmap_handle)
2185  else:
2186  if not args.hfile in winobjs.handle_pool:
2187  raise ValueError('unknown handle')
2188  ret = winobjs.handle_pool.add('filemapping', args.hfile)
2189  jitter.func_ret_stdcall(ret_ad, ret)
2190 
2191 
2193  kernel32_CreateFileMapping(jitter, whoami(), get_str_ansi)
2194 
2195 
2197  kernel32_CreateFileMapping(jitter, whoami(), get_str_unic)
2198 
2199 
2201  ret_ad, args = jitter.func_args_stdcall(["hfile", "flprotect",
2202  "dwfileoffsethigh",
2203  "dwfileoffsetlow",
2204  "length"])
2205 
2206  if not args.hfile in winobjs.handle_pool:
2207  raise ValueError('unknown handle')
2208  hmap = winobjs.handle_pool[args.hfile]
2209  if not hmap.info in winobjs.handle_pool:
2210  raise ValueError('unknown file handle')
2211 
2212  hfile_o = winobjs.handle_pool[hmap.info]
2213  fd = hfile_o.info
2214  fd.seek((args.dwfileoffsethigh << 32) | args.dwfileoffsetlow)
2215  data = fd.read(args.length) if args.length else fd.read()
2216  length = len(data)
2217 
2218  log.debug('mapp total: %x', len(data))
2219  access_dict = {
2220  0x0: 0,
2221  0x1: 0,
2222  0x2: PAGE_READ,
2223  0x4: PAGE_READ | PAGE_WRITE,
2224  0x10: PAGE_EXEC,
2225  0x20: PAGE_EXEC | PAGE_READ,
2226  0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
2227  0x100: 0,
2228  }
2229  # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
2230 
2231  if not args.flprotect in access_dict:
2232  raise ValueError('unknown access dw!')
2233 
2234  alloc_addr = winobjs.heap.alloc(jitter, len(data))
2235  jitter.vm.set_mem(alloc_addr, data)
2236 
2237  winobjs.handle_mapped[alloc_addr] = (hfile_o, args.dwfileoffsethigh,
2238  args.dwfileoffsetlow, length)
2239 
2240  jitter.func_ret_stdcall(ret_ad, alloc_addr)
2241 
2242 
2244  ret_ad, args = jitter.func_args_stdcall(['ad'])
2245 
2246  if not args.ad in winobjs.handle_mapped:
2247  raise NotImplementedError("Untested case")
2248  """
2249  hfile_o, dwfileoffsethigh, dwfileoffsetlow, length = winobjs.handle_mapped[ad]
2250  off = (dwfileoffsethigh<<32) | dwfileoffsetlow
2251  s = jitter.vm.get_mem(ad, length)
2252  hfile_o.info.seek(off)
2253  hfile_o.info.write(s)
2254  hfile_o.info.close()
2255  """
2256  jitter.func_ret_stdcall(ret_ad, 1)
2257 
2258 
2259 def kernel32_GetDriveType(jitter, funcname, get_str):
2260  ret_ad, args = jitter.func_args_stdcall(['pathname'])
2261 
2262  p = get_str(jitter, args.pathname)
2263  p = p.upper()
2264 
2265  ret = 0
2266  if p[0] == "C":
2267  ret = 3
2268 
2269  jitter.func_ret_stdcall(ret_ad, ret)
2270 
2271 
2273  kernel32_GetDriveType(jitter, whoami(), get_str_ansi)
2274 
2275 
2277  kernel32_GetDriveType(jitter, whoami(), get_str_unic)
2278 
2279 
2280 def kernel32_GetDiskFreeSpace(jitter, funcname, get_str):
2281  ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
2282  "lpsectorpercluster",
2283  "lpbytespersector",
2284  "lpnumberoffreeclusters",
2285  "lptotalnumberofclusters"])
2286  # rootpath = (get_str(jitter, args.lprootpathname)
2287  # if args.lprootpathname else "")
2288  jitter.vm.set_mem(args.lpsectorpercluster, pck32(8))
2289  jitter.vm.set_mem(args.lpbytespersector, pck32(0x200))
2290  jitter.vm.set_mem(args.lpnumberoffreeclusters, pck32(0x222222))
2291  jitter.vm.set_mem(args.lptotalnumberofclusters, pck32(0x333333))
2292  jitter.func_ret_stdcall(ret_ad, 1)
2293 
2294 
2296  kernel32_GetDiskFreeSpace(jitter, whoami(), get_str_ansi)
2297 
2298 
2300  kernel32_GetDiskFreeSpace(jitter, whoami(), get_str_unic)
2301 
2302 
2304  ret_ad, args = jitter.func_args_stdcall(["ad", "lpbuffer", "dwl"])
2305 
2306  access_dict = {
2307  0x0: 0,
2308  0x1: 0,
2309  0x2: PAGE_READ,
2310  0x4: PAGE_READ | PAGE_WRITE,
2311  0x10: PAGE_EXEC,
2312  0x20: PAGE_EXEC | PAGE_READ,
2313  0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
2314  0x100: 0,
2315  }
2316  access_dict_inv = dict([(x[1], x[0]) for x in access_dict.iteritems()])
2317 
2318  all_mem = jitter.vm.get_all_memory()
2319  found = None
2320  for basead, m in all_mem.iteritems():
2321  if basead <= args.ad < basead + m['size']:
2322  found = args.ad, m
2323  break
2324  if not found:
2325  raise ValueError('cannot find mem', hex(args.ad))
2326 
2327  if args.dwl != 0x1c:
2328  raise ValueError('strange mem len', hex(args.dwl))
2329  s = struct.pack('IIIIIII',
2330  args.ad,
2331  basead,
2332  access_dict_inv[m['access']],
2333  m['size'],
2334  0x1000,
2335  access_dict_inv[m['access']],
2336  0x01000000)
2337  jitter.vm.set_mem(args.lpbuffer, s)
2338  jitter.func_ret_stdcall(ret_ad, args.dwl)
2339 
2340 
2342  ret_ad, args = jitter.func_args_stdcall(["hprocess",
2343  "procaffmask",
2344  "systemaffmask"])
2345  jitter.vm.set_mem(args.procaffmask, pck32(1))
2346  jitter.vm.set_mem(args.systemaffmask, pck32(1))
2347  jitter.func_ret_stdcall(ret_ad, 1)
2348 
2349 
2350 def msvcrt_rand(jitter):
2351  ret_ad, _ = jitter.func_args_cdecl(0)
2352  jitter.func_ret_stdcall(ret_ad, 0x666)
2353 
2354 
2356  ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance",
2357  "p_distance_high",
2358  "movemethod"])
2359 
2360  if args.hwnd == winobjs.module_cur_hwnd:
2361  pass
2362  elif args.hwnd in winobjs.handle_pool:
2363  pass
2364  else:
2365  raise ValueError('unknown hwnd!')
2366 
2367  # data = None
2368  if args.hwnd in winobjs.files_hwnd:
2369  winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance)
2370  elif args.hwnd in winobjs.handle_pool:
2371  wh = winobjs.handle_pool[args.hwnd]
2372  # data = wh.info.seek(args.distance)
2373  else:
2374  raise ValueError('unknown filename')
2375  jitter.func_ret_stdcall(ret_ad, args.distance)
2376 
2377 
2379  ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance_l",
2380  "distance_h",
2381  "pnewfileptr",
2382  "movemethod"])
2383  distance = args.distance_l | (args.distance_h << 32)
2384  if distance:
2385  raise ValueError('Not implemented')
2386  if args.pnewfileptr:
2387  raise ValueError('Not implemented')
2388  if args.hwnd == winobjs.module_cur_hwnd:
2389  pass
2390  elif args.hwnd in winobjs.handle_pool:
2391  pass
2392  else:
2393  raise ValueError('unknown hwnd!')
2394 
2395  # data = None
2396  if args.hwnd in winobjs.files_hwnd:
2397  winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance)
2398  elif args.hwnd in winobjs.handle_pool:
2399  wh = winobjs.handle_pool[args.hwnd]
2400  # data = wh.info.seek(distance)
2401  else:
2402  raise ValueError('unknown filename')
2403  jitter.func_ret_stdcall(ret_ad, 1)
2404 
2405 
2407  ret_ad, args = jitter.func_args_stdcall(['hwnd'])
2408  if args.hwnd in winobjs.handle_pool:
2409  wh = winobjs.handle_pool[args.hwnd]
2410  wh.info.seek(0, 2)
2411  else:
2412  raise ValueError('unknown filename')
2413  jitter.func_ret_stdcall(ret_ad, 1)
2414 
2415 
2417  ret_ad, args = jitter.func_args_stdcall(['hwnd'])
2418  if args.hwnd in winobjs.handle_pool:
2419  pass
2420  else:
2421  raise ValueError('unknown filename')
2422  jitter.func_ret_stdcall(ret_ad, 1)
2423 
2424 
2426  ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
2427  "nnumberofbytestowrite",
2428  "lpnumberofbyteswrite",
2429  "lpoverlapped"])
2430  data = jitter.vm.get_mem(args.lpbuffer, args.nnumberofbytestowrite)
2431 
2432  if args.hwnd == winobjs.module_cur_hwnd:
2433  pass
2434  elif args.hwnd in winobjs.handle_pool:
2435  pass
2436  else:
2437  raise ValueError('unknown hwnd!')
2438 
2439  if args.hwnd in winobjs.files_hwnd:
2440  winobjs.files_hwnd[winobjs.module_cur_hwnd].write(data)
2441  elif args.hwnd in winobjs.handle_pool:
2442  wh = winobjs.handle_pool[args.hwnd]
2443  wh.info.write(data)
2444  else:
2445  raise ValueError('unknown filename')
2446 
2447  if (args.lpnumberofbyteswrite):
2448  jitter.vm.set_mem(args.lpnumberofbyteswrite, pck32(len(data)))
2449 
2450  jitter.func_ret_stdcall(ret_ad, 1)
2451 
2452 
2454  ret_ad, args = jitter.func_args_stdcall(["c"])
2455  ret = 0 if args.c & 0x20 else 1
2456  jitter.func_ret_stdcall(ret_ad, ret)
2457 
2458 
2460  ret_ad, args = jitter.func_args_stdcall(["c"])
2461  ret = 1 if args.c & 0x20 else 0
2462  jitter.func_ret_stdcall(ret_ad, ret)
2463 
2464 
2466  ret_ad, _ = jitter.func_args_stdcall(0)
2467  jitter.func_ret_stdcall(ret_ad, 0x409) # encglish
2468 
2469 
2470 def msvcrt_malloc(jitter):
2471  ret_ad, args = jitter.func_args_cdecl(["msize"])
2472  addr = winobjs.heap.alloc(jitter, args.msize)
2473  jitter.func_ret_cdecl(ret_ad, addr)
2474 
2475 
2476 def msvcrt_free(jitter):
2477  ret_ad, _ = jitter.func_args_cdecl(["ptr"])
2478  jitter.func_ret_cdecl(ret_ad, 0)
2479 
2480 
2481 def msvcrt_fseek(jitter):
2482  ret_ad, args = jitter.func_args_cdecl(['stream', 'offset', 'orig'])
2483  fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
2484 
2485  if not fd in winobjs.handle_pool:
2486  raise NotImplementedError("Untested case")
2487  o = winobjs.handle_pool[fd]
2488  o.info.seek(args.offset, args.orig)
2489  jitter.func_ret_cdecl(ret_ad, 0)
2490 
2491 
2492 def msvcrt_ftell(jitter):
2493  ret_ad, args = jitter.func_args_cdecl(["stream"])
2494  fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
2495 
2496  if not fd in winobjs.handle_pool:
2497  raise NotImplementedError("Untested case")
2498  o = winobjs.handle_pool[fd]
2499  off = o.info.tell()
2500  jitter.func_ret_cdecl(ret_ad, off)
2501 
2502 
2503 def msvcrt_rewind(jitter):
2504  ret_ad, args = jitter.func_args_cdecl(["stream"])
2505  fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
2506  if not fd in winobjs.handle_pool:
2507  raise NotImplementedError("Untested case")
2508  o = winobjs.handle_pool[fd]
2509  # off = o.info.seek(0, 0)
2510  jitter.func_ret_cdecl(ret_ad, 0)
2511 
2512 
2513 def msvcrt_fread(jitter):
2514  ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"])
2515  fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
2516  if not fd in winobjs.handle_pool:
2517  raise NotImplementedError("Untested case")
2518 
2519  data = winobjs.handle_pool[fd].info.read(args.size * args.nmemb)
2520  jitter.vm.set_mem(args.buf, data)
2521  jitter.func_ret_cdecl(ret_ad, args.nmemb)
2522 
2523 
2524 def msvcrt_fclose(jitter):
2525  ret_ad, args = jitter.func_args_cdecl(['stream'])
2526  fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
2527 
2528  if not fd in winobjs.handle_pool:
2529  raise NotImplementedError("Untested case")
2530  o = winobjs.handle_pool[fd]
2531  # off = o.info.close()
2532  jitter.func_ret_cdecl(ret_ad, 0)
2533 
2534 
2535 def msvcrt_atexit(jitter):
2536  ret_ad, _ = jitter.func_args_cdecl(["func"])
2537  jitter.func_ret_cdecl(ret_ad, 0)
2538 
2539 
2541  ret_ad, args = jitter.func_args_stdcall(["hwnd", "lptext",
2542  "lpcaption", "utype"])
2543 
2544  text = get_str_ansi(jitter, args.lptext)
2545  caption = get_str_ansi(jitter, args.lpcaption)
2546 
2547  log.info('Caption: %r Text: %r', caption, text)
2548 
2549  jitter.func_ret_stdcall(ret_ad, 0)
2550 
2551 
2552 def kernel32_myGetTempPath(jitter, func):
2553  ret_ad, args = jitter.func_args_stdcall(["l", "buf"])
2554  l = 'c:\\temp\\'
2555  if len(l) < args.l:
2556  jitter.vm.set_mem(args.buf, func(l + '\x00'))
2557  jitter.func_ret_stdcall(ret_ad, len(l))
2558 
2559 
2561  kernel32_myGetTempPath(jitter, set_str_ansi)
2562 
2563 
2565  kernel32_myGetTempPath(jitter, set_str_unic)
2566 
2567 
2568 temp_num = 0
2569 
2570 
2572  global temp_num
2573  ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"])
2574 
2575  temp_num += 1
2576  ext = get_str_ansi(jitter, args.ext) if args.ext else 'tmp'
2577  path = get_str_ansi(jitter, args.path) if args.path else "xxx"
2578  fname = path + "\\" + "temp%.4d" % temp_num + "." + ext
2579  jitter.vm.set_mem(args.buf, fname)
2580 
2581  jitter.func_ret_stdcall(ret_ad, 0)
2582 
2583 
2585  fileattrib = 0
2586  creationtime = 0
2587  lastaccesstime = 0
2588  lastwritetime = 0
2589  filesizehigh = 0
2590  filesizelow = 0
2591  dwreserved0 = 0
2592  dwreserved1 = 0x1337beef
2593  cfilename = ""
2594  alternamefilename = ""
2595 
2596  def __init__(self, **kargs):
2597  for k, v in kargs.items():
2598  setattr(self, k, v)
2599 
2600  def toStruct(self):
2601  s = struct.pack('=IQQQIIII',
2602  self.fileattrib,
2603  self.creationtime,
2604  self.lastaccesstime,
2605  self.lastwritetime,
2606  self.filesizehigh,
2607  self.filesizelow,
2608  self.dwreserved0,
2609  self.dwreserved1)
2610  fname = self.cfilename + '\x00' * MAX_PATH
2611  fname = fname[:MAX_PATH]
2612  s += fname
2613  fname = self.alternamefilename + '\x00' * 14
2614  fname = fname[:14]
2615  s += fname
2616  return s
2617 
2618 
2620 
2621  def __init__(self):
2622  self.patterns = {}
2623  self.flist = []
2624  # handle number -> (flist index, current index in list)
2625  self.handles = {}
2626 
2627  def add_list(self, pattern, flist):
2628  index = len(self.flist)
2629  self.flist.append(flist)
2630 
2631  self.patterns[pattern] = index
2632 
2633  def findfirst(self, pattern):
2634  assert(pattern in self.patterns)
2635  findex = self.patterns[pattern]
2636  h = len(self.handles) + 1
2637  self.handles[h] = [findex, 0]
2638  return h
2639 
2640  def findnext(self, h):
2641  assert(h in self.handles)
2642  findex, index = self.handles[h]
2643  if index >= len(self.flist[findex]):
2644  return None
2645  fname = self.flist[findex][index]
2646  self.handles[h][1] += 1
2647 
2648  return fname
2649 
2650 
2652  ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"])
2653 
2654  filepattern = get_str_ansi(jitter, args.pfilepattern)
2655  h = winobjs.find_data.findfirst(filepattern)
2656 
2657  fname = winobjs.find_data.findnext(h)
2658  fdata = win32_find_data(cfilename=fname)
2659 
2660  jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct())
2661  jitter.func_ret_stdcall(ret_ad, h)
2662 
2663 
2665  ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"])
2666 
2667  fname = winobjs.find_data.findnext(args.handle)
2668  if fname is None:
2669  ret = 0
2670  else:
2671  ret = 1
2672  fdata = win32_find_data(cfilename=fname)
2673  jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct())
2674 
2675  jitter.func_ret_stdcall(ret_ad, ret)
2676 
2677 
2679  ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
2680  sysinfo = systeminfo()
2681  jitter.vm.set_mem(args.sys_ptr, sysinfo.pack())
2682  jitter.func_ret_stdcall(ret_ad, 0)
2683 
2684 
2685 def raw2guid(r):
2686  o = struct.unpack('IHHHBBBBBB', r)
2687  return '{%.8X-%.4X-%.4X-%.4X-%.2X%.2X%.2X%.2X%.2X%.2X}' % o
2688 
2689 
2690 digs = string.digits + string.lowercase
2691 
2692 
2693 def int2base(x, base):
2694  if x < 0:
2695  sign = -1
2696  elif x == 0:
2697  return '0'
2698  else:
2699  sign = 1
2700  x *= sign
2701  digits = []
2702  while x:
2703  digits.append(digs[x % base])
2704  x /= base
2705  if sign < 0:
2706  digits.append('-')
2707  digits.reverse()
2708  return ''.join(digits)
2709 
2710 
2711 def msvcrt__ultow(jitter):
2712  ret_ad, args = jitter.func_args_cdecl(["value", "p", "radix"])
2713 
2714  value = args.value & 0xFFFFFFFF
2715  if not args.radix in [10, 16, 20]:
2716  raise ValueError("Not tested")
2717  s = int2base(value, args.radix)
2718  jitter.vm.set_mem(args.p, set_str_unic(s + "\x00"))
2719  jitter.func_ret_cdecl(ret_ad, args.p)
2720 
2721 
2722 def msvcrt_myfopen(jitter, func):
2723  ret_ad, args = jitter.func_args_cdecl(["pfname", "pmode"])
2724 
2725  fname = func(jitter, args.pfname)
2726  rw = func(jitter, args.pmode)
2727  log.debug(fname)
2728  log.debug(rw)
2729 
2730  if rw in ['r', 'rb', 'wb+']:
2731  sb_fname = windows_to_sbpath(fname)
2732  h = open(sb_fname, rw)
2733  eax = winobjs.handle_pool.add(sb_fname, h)
2734  dwsize = 0x20
2735  alloc_addr = winobjs.heap.alloc(jitter, dwsize)
2736  pp = pck32(0x11112222) + pck32(0) + pck32(0) + pck32(0) + pck32(eax)
2737  #pdw(0x11112222)
2738  jitter.vm.set_mem(alloc_addr, pp)
2739 
2740  else:
2741  raise ValueError('unknown access mode %s' % rw)
2742 
2743  jitter.func_ret_cdecl(ret_ad, alloc_addr)
2744 
2745 
2746 def msvcrt__wfopen(jitter):
2747  msvcrt_myfopen(jitter, get_str_unic)
2748 
2749 
2750 def msvcrt_fopen(jitter):
2751  msvcrt_myfopen(jitter, get_str_ansi)
2752 
2753 
2754 def msvcrt_strlen(jitter):
2755  ret_ad, args = jitter.func_args_cdecl(["src"])
2756 
2757  s = get_str_ansi(jitter, args.src)
2758  jitter.func_ret_cdecl(ret_ad, len(s))
tuple pck16
Definition: utils.py:11
tuple upck32
Definition: utils.py:8
tuple pck32
Definition: utils.py:12