Skip to content

Commit

Permalink
Merge pull request #885 from crass/win-file-opts-16bit
Browse files Browse the repository at this point in the history
Add windows 16bit compatibility file api
  • Loading branch information
xwings authored Aug 21, 2021
2 parents cb7be68 + 1ddbe6d commit 35db51a
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This file details the changelog of Qiling Framework.
- Added more Posix syscall
- Bugfix: GDB server on MIPS binary
- Major refactor of Windows DLL
- Add Win32 16bit compatibility file api


------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion qiling/os/windows/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
ACCESS_MASK = INT
BOOLEAN = INT
GROUP = INT
HFILE = INT
OBJECT_INFORMATION_CLASS = INT
PROCESSINFOCLASS = INT
SOCKET = INT
Expand Down Expand Up @@ -157,4 +158,4 @@
REFIID = POINTER
REGSAM = POINTER
UINT_PTR = POINTER
ULONG_PTR = POINTER
ULONG_PTR = POINTER
19 changes: 19 additions & 0 deletions qiling/os/windows/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,3 +687,22 @@
# https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation
HANDLE_FLAG_INHERIT = 0x1
HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x2

# https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfile
OF_READ = 0x00000000
OF_WRITE = 0x00000001
OF_READWRITE = 0x00000002
OF_PARSE = 0x00000100
OF_DELETE = 0x00000200
OF_VERIFY = 0x00000400
OF_CANCEL = 0x00000800
OF_CREATE = 0x00001000
OF_PROMPT = 0x00002000
OF_EXIST = 0x00004000
OF_REOPEN = 0x00008000

OF_SHARE_COMPAT = 0x00000000
OF_SHARE_EXCLUSIVE = 0x00000010
OF_SHARE_DENY_WRITE = 0x00000020
OF_SHARE_DENY_READ = 0x00000030
OF_SHARE_DENY_NONE = 0x00000040
137 changes: 137 additions & 0 deletions qiling/os/windows/dlls/kernel32/winbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

import os
import configparser

from qiling import Qiling
Expand All @@ -13,6 +14,142 @@
from qiling.os.windows.structs import OsVersionInfoExA
from qiling.os.windows.utils import cmp

# HFILE _lclose(
# HFILE hFile
# );
@winsdkapi(cc=STDCALL, params={
'hFile' : HFILE
})
def hook__lclose(ql: Qiling, address: int, params):
fileno = params["hFile"]

if fileno < 0:
return HFILE_ERROR

os.close(fileno)

return fileno

# HFILE _lcreat(
# LPCSTR lpPathName,
# int iAttribute
# );
@winsdkapi(cc=STDCALL, params={
'lpPathName' : LPCSTR,
'iAttribute' : INT
})
def hook__lcreat(ql: Qiling, address: int, params):
s_lpPathName = params["lpPathName"]
iAttribute = params["iAttribute"]

# There are 4 access bits, we don't care about hidden or system
mode = "w+b"
if iAttribute & 2:
mode += "r+b"

try:
f = ql.os.fs_mapper.open(s_lpPathName, mode)
except FileNotFoundError:
ql.os.last_error = ERROR_FILE_NOT_FOUND
return -1

# The file obj will be closed, dup the file handle to keep open
return os.dup(f.fileno())

# HFILE _lopen(
# LPCSTR lpPathName,
# int iReadWrite
# );
@winsdkapi(cc=STDCALL, params={
'lpPathName' : LPCSTR,
'iReadWrite' : INT
})
def hook__lopen(ql: Qiling, address: int, params):
s_lpPathName = params["lpPathName"]
iReadWrite = params["iReadWrite"]

# access mask DesiredAccess
mode = ""
if iReadWrite & (OF_WRITE | OF_READWRITE):
mode += "wb"
else:
mode += "r"

try:
f = ql.os.fs_mapper.open(s_lpPathName, mode)
except FileNotFoundError:
ql.os.last_error = ERROR_FILE_NOT_FOUND
return -1

# The file obj will be closed, dup the file handle to keep open
return os.dup(f.fileno())

# UINT _lread(
# HFILE hFile,
# LPVOID lpBuffer,
# UINT uBytes
# );
@winsdkapi(cc=STDCALL, params={
'hFile' : HFILE,
'lpBuffer' : LPVOID,
'uBytes' : UINT
})
def hook__lread(ql: Qiling, address: int, params):
fileno = params["hFile"]
lpBuffer = params["lpBuffer"]
uBytes = params["uBytes"]

if fileno < 0:
return HFILE_ERROR

data = os.read(fileno, uBytes)
ql.mem.write(lpBuffer, data)

return len(data)

# LONG _llseek(
# HFILE hFile,
# LONG lOffset,
# int iOrigin
# );
@winsdkapi(cc=STDCALL, params={
'hFile' : HFILE,
'lOffset' : LONG,
'iOrigin' : INT
})
def hook__llseek(ql: Qiling, address: int, params):
fileno = params["hFile"]
lOffset = params["lOffset"]
iOrigin = params["iOrigin"]

if fileno < 0:
return HFILE_ERROR

return os.lseek(fileno, lOffset, iOrigin)

# UINT _lwrite(
# HFILE hFile,
# LPCCH lpBuffer,
# UINT uBytes
# );
@winsdkapi(cc=STDCALL, params={
'hFile' : HFILE,
'lpBuffer' : LPCCH,
'uBytes' : UINT
})
def hook__lwrite(ql: Qiling, address: int, params):
fileno = params["hFile"]
lpBuffer = params["lpBuffer"]
uBytes = params["uBytes"]

if fileno < 0:
return HFILE_ERROR

wbuf = ql.mem.read(lpBuffer, uBytes)
len = os.write(fileno, wbuf)

return len

# __analysis_noreturn VOID FatalExit(
# int ExitCode
# );
Expand Down

0 comments on commit 35db51a

Please sign in to comment.