
Indirect syscalls + DInvoke को सरल बनाया गया।
अप्रत्यक्ष सिस्कॉल्स + DInvoke को सरल बनाया गया।
आपके अपने Nim प्रोजेक्ट्स में सीधे import करने के लिए डिज़ाइन की गई, nimvoke अप्रत्यक्ष सिस्टम कॉल और DInvoke-शैली डेलिगेट घोषणाओं की जटिलताओं को छिपाने के लिए मैक्रोज़ का उपयोग करती है। इस लाइब्रेरी का उद्देश्य उपयोग में आसान और आउट-ऑफ़-द-बॉक्स अपेक्षाकृत op-sec अनुकूल होना है। मैक्रोज़ में उपयोग किए जाने वाले फ़ंक्शन और लाइब्रेरी नाम कंपाइल-टाइम पर हैश किए जाते हैं, और किसी भी हुक्स के बावजूद SSN और syscall निर्देश पते प्राप्त किए जाते हैं। सभी syscalls ntdll.dll में सही syscall निर्देश से होकर गुजरते हैं।
nimble से इंस्टॉल करें (nimble install https://github.com/nbaertsch/nimvoke), फिर प्रासंगिक लाइब्रेरी को import करें और संबंधित मैक्रो को कॉल करें। अधिक विवरण के लिए examples देखें।
DInvoke:
import winim/lean
import nimvoke/dinvoke
dinvokeDefine(
ZwAllocateVirtualMemory,
"ntdll.dll",
proc (ProcessHandle: Handle, BaseAddress: PVOID, ZeroBits: ULONG_PTR, RegionSize: PSIZE_T, AllocationType: ULONG, Protect: ULONG): NTSTATUS {.stdcall.}
)
var
hProcess: HANDLE = 0xFFFFFFFFFFFFFFFF
shellcodeSize: SIZE_T = 1000
baseAddr: PVOID
status: NTSTATUS
status = ZwAllocateVirtualMemory(
hProcess,
&baseAddr,
0,
&shellcodeSize,
MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE)
Syscalls:
import winim/lean
import nimvoke/syscalls
var
hProcess: HANDLE = 0xFFFFFFFFFFFFFFFF
shellcodeSize: SIZE_T = 1000
baseAddr: PVOID
status: NTSTATUS
status = syscall(NtAllocateVirtualMemory,
hProcess,
&baseAddr,
0,
&shellcodeSize,
MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE
)
सभी Nim बाइनरी कोर Win32 फ़ंक्शनों का एक सेट import करती हैं। अन्य सभी Win32 फ़ंक्शन dynlib के माध्यम से हल किए जाते हैं, जो रनटाइम पर फ़ंक्शनों को हल करने के लिए GetProcAddress और LoadLibraryA का उपयोग करता है। यह DInvoke कार्यान्वयन उन नए फ़ंक्शनों को उजागर होने से रोक सकता है जो अन्य कोड द्वारा उपयोग नहीं किए जाते हैं (चाहे वह nim runtime/GC हो या dynlib के माध्यम से import करने वाला stdlib कोड), लेकिन यह Nim के कोर imports को हटा नहीं सकता या std या तृतीय-पक्ष लाइब्रेरीज़ के व्यवहार को बदल नहीं सकता।
Import करने पर, nimvoke/syscalls सभी syscalls को खोजने और आवश्यक डेटा निकालने के लिए ntdll.dll के EAT को पार्स करेगा। सभी syscalls की जानकारी मेमोरी में संग्रहीत की जाती है।
type
Syscall* = object
pName*: PCHAR
ord*: WORD
pFunc*: PVOID
pSyscall*: PVOID = NULL
ssn*: WORD
hooked*: bool
...
syscallSeq: seq[Syscall] # stores all syscall data
syscallTable* = initTable[string, ptr Syscall]() # maps syscall `Zw` hashed-name to `Syscall` object's in the `syscallSeq`
SSN प्राप्त करना सभी syscalls को उनके पते के आधार पर क्रमबद्ध करके और उन्हें गिनकर किया जाता है। यह विधि किसी भी हुकिंग के बावजूद काम करनी चाहिए। मेमोरी में कोई फ़ंक्शन नाम स्ट्रिंग संग्रहीत नहीं की जाती, लेकिन हैश की गणना करने के लिए ntdll.dll के EAT में फ़ंक्शन नाम स्ट्रिंग्स का एक पॉइंटर रखा जाता है।
Syscalls SSN को eax में ले जाने, आर्ग्युमेंट्स तैयार करने और ntdll.dll में सही syscall निर्देश पर कूदने के लिए एक ही ट्रैम्पोलिन (जो FreshyCalls से लिया गया है) का उपयोग करते हैं। यह ट्रैम्पोलिन एक नए प्राइवेट हीप पर आवंटित किया जाता है।
यदि आप इस syscall इनिशियलाइज़ेशन कोड से पहले कोड चलाना चाहते हैं (जैसे सैंडबॉक्स एवेशन या पर्यावरणीय कीिंग के लिए), तो आपको इसे अपने कोड में import nimvoke/syscalls स्टेटमेंट से पहले कॉल करना होगा।
सुझाव हैं? Issue खोलें! PR भी स्वागत योग्य हैं।