| juntalis Newbie cheater
 
 ![]() Reputation: 2 
 Joined: 13 Mar 2013
 Posts: 12
 
 
 | 
			
				|  Posted: Sun Dec 07, 2014 12:04 pm    Post subject: Lua FFI Plugin |     |  
				| 
 |  
				| Edit: Not sure when or what changed, but it looks like this plugin is no longer needed, as the ffi C-extension loads and works fine when the binaries are placed in the clibs32/clibs64 folders. I went ahead and added a new release containing the FFI binaries built against CE's customized Lua 5.3. (Up to date as of CE 6.5) 
 Original Post
 
 
 [/quote] 	  | Quote: |  	  | I wrote (using the word loosely) this plugin sometime back in 2013, and ended up losing interest in the project before I ever got around to making it release-worthy. Furthermore, I took a strange approach when loading in the Lua extension, and I don't really remember why. Regardless, it's worked for the last year, and I probably won't ever go back and clean it up, so I figured I'd go ahead and release it.
 
 I've gone ahead and thrown the project up on github, but since I'm unable to post urls at this time, you'll have to navigate there on your own: juntalis/ce-luacontrib
 
 Examples
 
 
  	  | Code: |  	  | local ffi = require('ffi')
 
 -- Load all of our DLLs
 local ntdll = ffi.load('ntdll.dll')
 local kernel32 = ffi.load('kernel32.dll')
 local user32 = ffi.load('user32.dll')
 local msvcrt = ffi.load('msvcrt.dll')
 
 --[[--
 CRT Declarations (msvcrt.dll)
 --]]--
 ffi.cdef[[
 unsigned int wcstombs(char* s, const wchar_t* w, unsigned int c);
 unsigned int mbstowcs(wchar_t* w, const char* s, unsigned int c);
 unsigned int wcslen(const wchar_t* s);
 unsigned int strlen(const char* s);
 char *strcpy(char* d, const char* s);
 ]]
 
 --[[--
 Lua wrapper functions for the above declarations.
 --]]--
 
 function wcslen(ws)
 return tonumber(
 msvcrt.wcslen(
 ffi.cast('const wchar_t*', ws)
 )
 )
 end
 
 function wstr2str(ws, length)
 local szbuf = length or wcslen(ws)
 local buf = ffi.new('char[?]', szbuf+1)
 if msvcrt.wcstombs(buf, ffi.cast('const wchar_t*', ws), szbuf) == -1 then
 return nil
 end
 return ffi.string(buf, szbuf)
 end
 
 function str2wstr(s)
 local szbuf = s:len()
 local buf = ffi.new('wchar_t[?]', szbuf+1)
 if msvcrt.mbstowcs(buf, s, szbuf) == -1 then
 return nil
 end
 return buf
 end
 
 function str2cstr(s)
 local szbuf = s:len()
 local buf = ffi.new('char[?]', szbuf+1)
 msvcrt.strcpy(buf, s)
 return buf
 end
 
 --[[--
 Native Declarations (ntdll.dll)
 --]]--
 ffi.cdef[[
 typedef union _LARGE_INTEGER {
 struct
 {
 unsigned long   LowPart;
 long         HighPart;
 } s;
 struct
 {
 unsigned long   LowPart;
 long         HighPart;
 } u;
 long long   QuadPart;
 } LARGE_INTEGER;
 
 typedef struct _UNICODE_STRING {
 unsigned short   Length;
 unsigned short   MaximumLength;
 wchar_t         ***Buffer;
 } UNICODE_STRING;
 
 typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD {
 unsigned long   NextEntryOffset;
 unsigned long   NumberOfThreads;
 LARGE_INTEGER   SpareLi1;
 LARGE_INTEGER   SpareLi2;
 LARGE_INTEGER   SpareLi3;
 LARGE_INTEGER   CreateTime;
 LARGE_INTEGER   UserTime;
 LARGE_INTEGER   KernelTime;
 UNICODE_STRING   ImageName;
 long         BasePriority;
 void         *UniqueProcessId;
 unsigned long   InheritedFromUniqueProcessId;
 unsigned long   HandleCount;
 unsigned char   Reserved4[4];
 void         *Reserved5[11];
 unsigned long   PeakPagefileUsage;
 unsigned long   PrivatePageCount;
 LARGE_INTEGER   Reserved6[6];
 } SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD;
 
 long NtQuerySystemInformation(unsigned long, void*, unsigned long, unsigned long*);
 ]]
 
 -- Constants
 local SystemProcessInformation = 5
 
 --[[--
 Given a process's PID, return the filename of the executable.
 --]]--
 function pid2name(pid)
 local status, result, psinfo, retlength =
 0, nil,
 ffi.cast('PSYSTEM_PROCESS_INFORMATION_DETAILD', ffi.new('unsigned char[?]', 102400)),
 ffi.new('unsigned long[1]')
 
 status = tonumber(ntdll.NtQuerySystemInformation(
 SystemProcessInformation,
 ffi.cast('void*', psinfo),
 102400,
 result
 ))
 
 if status ~= 0 then return result end
 while (status == 0) and (tonumber(psinfo.NextEntryOffset) > 0) do
 if pid == tonumber(psinfo.UniqueProcessId) then
 result = cutil.wstr2str(psinfo.ImageName.Buffer, psinfo.ImageName.Length - 4)
 status = 1
 else
 psinfo = ffi.cast(
 'PSYSTEM_PROCESS_INFORMATION_DETAILD',
 tonumber(ffi.cast('void*', psinfo)) + psinfo.NextEntryOffset
 )
 end
 end
 
 return result
 end
 
 --[[--
 Win32 API Declarations (user32.dll, kernel32.dll)
 --]]--
 ffi.cdef[[
 typedef void* HWND, *LPARAM;
 typedef signed long BOOL;
 typedef unsigned long DWORD;
 typedef DWORD* LPDWORD;
 typedef BOOL(__stdcall* WNDENUMPROC)(HWND hWnd, LPARAM lParam);
 
 typedef struct _ENUMPARAM {
 HWND hWnd;
 DWORD PID;
 } ENUMPARAM, *PENUMPARAM;
 
 HWND SetFocus(HWND hWnd);
 DWORD GetCurrentThreadId(void);
 HWND GetForegroundWindow(void);
 BOOL BringWindowToTop(HWND hWnd);
 BOOL SetForegroundWindow(HWND hWnd);
 BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
 DWORD GetWindowThreadProcessId(HWND hWnd, LPDWORD lpdwProcessId);
 BOOL AttachThreadInput(DWORD idAttach, DWORD idAttachTo, BOOL fAttach);
 ]]
 
 -- Constants & Explicit Imports
 local TRUE,FALSE = 1,0
 local GetCurrentThreadId = kernel32.GetCurrentThreadId
 local SetFocus = user32.SetFocus
 local GetForegroundWindow = user32.GetForegroundWindow
 local BringWindowToTop = user32.BringWindowToTop
 local SetForegroundWindow = user32.SetForegroundWindow
 local EnumWindows = user32.EnumWindows
 local GetWindowThreadProcessId = user32.GetWindowThreadProcessId
 local AttachThreadInput = user32.AttachThreadInput
 
 local enumWndsProc = ffi.cast('WNDENUMPROC', function(hWnd, lParam)
 local lpdwPID = ffi.new('DWORD[1]')
 local ep = ffi.cast('PENUMPARAM', lParam)
 GetWindowThreadProcessId(hWnd, lpdwPID)
 if ep[0].PID == lpdwPID[0] then
 ep[0].hWnd = hWnd
 return FALSE
 end
 return TRUE
 end)
 
 -- Obviously this function suffers a few serious
 -- flaws. It only returns the first window found
 -- for a particular PID, so if your target has more
 -- than one window open, there's no guarantee that
 -- you're finding the window you're looking for.
 pid2hwnd = function(pid)
 pid = pid or getOpenedProcessID()
 local ep = ffi.new('ENUMPARAM[1]')
 ep[0].hWnd = nil
 ep[0].PID  = pid
 EnumWindows(enumWndsProc, ffi.cast('LPARAM', ep))
 return ep[0].hWnd
 end
 
 setForegroundWindow = function(hWnd)
 local dwFgPID = ffi.new('DWORD[1]')
 local hWndFg = GetForegroundWindow()
 local dwFgTID = GetWindowThreadProcessId(hWndFg, dwFgPID)
 local dwMyTID = GetCurrentThreadId()
 AttachThreadInput(dwMyTID, dwFgTID, TRUE)
 SetForegroundWindow(hWnd)
 BringWindowToTop(hWnd)
 SetFocus(hWnd)
 AttachThreadInput(dwMyTID, dwFgTID, False)
 end
 
 | 
 
 One of the ways I've been using it:
 
 
  	  | Code: |  	  | --[[--
 Code below is in its own file under the lua folder.(startup.lua)
 --]]--
 function _M.onOpenProcess(pid)
 local procname = ntdll.pid2name(pid)
 while (pid == 0) or (procname == nil) do
 sleep(500)
 pid = getOpenedProcessID()
 procname = ntdll.pid2name(pid)
 end
 
 startAutoChecks()
 for i,fn in ipairs(getpriv('onstartup')) do fn() end
 setpriv('onstartup', nil)
 end
 
 --[[--
 Code found in my main autorun script.
 --]]--
 onOpenProcess = require('startup').onOpenProcess
 
 | 
 
 
 Note: Not sure why noblanks.exe is in this project's folder, but here's the source for that, too: (The executable was compiled using pypy translators)
 
 
  	  | Code: |  	  | import os, sys
 
 
 def entry_point(argv):
 #stdin = os.open(0, os.O_RDONLY, 0777)
 stdin = 0
 app_running = True
 while app_running:
 # Readline implementation.
 line = ""
 count = 0
 while True:
 c = os.read(stdin, 1)
 if len(c) == 0:
 app_running = False
 break
 elif c == '\n':
 break
 elif c == "\r":
 continue
 elif c != ' ' and c != '\t':
 count += 1
 line += c
 
 # Check count. If 0, skip the line.
 if count == 0:
 continue
 print line
 return 0
 
 def target(*args):
 return entry_point, None
 
 if __name__ == "__main__":
 entry_point(sys.argv)
 
 | 
 | 
 |  |