Advertisement
Guest User

Untitled

a guest
Nov 13th, 2020
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 114.80 KB | None | 0 0
  1. /*
  2.  
  3. Decoda
  4. Copyright (C) 2007-2013 Unknown Worlds Entertainment, Inc.
  5.  
  6. This file is part of Decoda.
  7.  
  8. Decoda is free software: you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation, either version 3 of the License, or
  11. (at your option) any later version.
  12.  
  13. Decoda is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Decoda. If not, see <http://www.gnu.org/licenses/>.
  20.  
  21. */
  22.  
  23. #include "LuaDll.h"
  24. #include "Hook.h"
  25. #include "DebugBackend.h"
  26. #include "StdCall.h"
  27. #include "CriticalSection.h"
  28. #include "CriticalSectionLock.h"
  29. #include "DebugHelp.h"
  30.  
  31. #include <windows.h>
  32. #include <tlhelp32.h>
  33. #include <psapi.h>
  34. #include <windows.h>
  35. #include <malloc.h>
  36. #include <assert.h>
  37. #include <set>
  38. #include <hash_map>
  39. #include <hash_set>
  40.  
  41. // Macro for convenient pointer addition.
  42. // Essentially treats the last two parameters as DWORDs. The first
  43. // parameter is used to typecast the result to the appropriate pointer type.
  44. #define MAKE_PTR(cast, ptr, addValue ) (cast)( (DWORD)(ptr)+(DWORD)(addValue))
  45.  
  46. // When this is defined, additional information about what's going on will be
  47. // output for debugging.
  48. //#define VERBOSE
  49. //#define LOG
  50.  
  51. typedef const char* (__stdcall *lua_Reader_stdcall) (lua_State*, void*, size_t*);
  52. typedef void (__stdcall *lua_Hook_stdcall) (lua_State*, lua_Debug*);
  53.  
  54. typedef lua_State* (*lua_open_cdecl_t) (int stacksize);
  55. typedef lua_State* (*lua_open_500_cdecl_t) ();
  56. typedef lua_State* (*lua_newstate_cdecl_t) (lua_Alloc, void*);
  57. typedef void (*lua_close_cdecl_t) (lua_State*);
  58. typedef lua_State* (*lua_newthread_cdecl_t) (lua_State*);
  59. typedef int (*lua_error_cdecl_t) (lua_State*);
  60. typedef int (*lua_sethook_cdecl_t) (lua_State*, lua_Hook, int, int);
  61. typedef int (*lua_getinfo_cdecl_t) (lua_State*, const char*, lua_Debug* ar);
  62. typedef void (*lua_remove_cdecl_t) (lua_State*, int);
  63. typedef void (*lua_settable_cdecl_t) (lua_State*, int);
  64. typedef void (*lua_gettable_cdecl_t) (lua_State*, int);
  65. typedef void (*lua_rawget_cdecl_t) (lua_State *L, int idx);
  66. typedef void (*lua_rawgeti_cdecl_t) (lua_State *L, int idx, int n);
  67. typedef void (*lua_rawset_cdecl_t) (lua_State *L, int idx);
  68. typedef void (*lua_pushstring_cdecl_t) (lua_State*, const char*);
  69. typedef void (*lua_pushlstring_cdecl_t) (lua_State*, const char*, size_t);
  70. typedef int (*lua_type_cdecl_t) (lua_State*, int);
  71. typedef const char* (*lua_typename_cdecl_t) (lua_State*, int);
  72. typedef void (*lua_settop_cdecl_t) (lua_State*, int);
  73. typedef const char* (*lua_getlocal_cdecl_t) (lua_State*, const lua_Debug*, int);
  74. typedef const char* (*lua_setlocal_cdecl_t) (lua_State*, const lua_Debug*, int);
  75. typedef int (*lua_getstack_cdecl_t) (lua_State*, int, lua_Debug*);
  76. typedef void (*lua_insert_cdecl_t) (lua_State*, int);
  77. typedef void (*lua_pushnil_cdecl_t) (lua_State*);
  78. typedef void (*lua_pushcclosure_cdecl_t) (lua_State*, lua_CFunction, int);
  79. typedef void (*lua_pushvalue_cdecl_t) (lua_State*, int);
  80. typedef void (*lua_pushinteger_cdecl_t) (lua_State*, int);
  81. typedef void (*lua_pushnumber_cdecl_t) (lua_State*, lua_Number);
  82. typedef const char* (*lua_tostring_cdecl_t) (lua_State*, int);
  83. typedef const char* (*lua_tolstring_cdecl_t) (lua_State*, int, size_t*);
  84. typedef int (*lua_toboolean_cdecl_t) (lua_State*, int);
  85. typedef int (*lua_tointeger_cdecl_t) (lua_State*, int);
  86. typedef lua_Integer (*lua_tointegerx_cdecl_t) (lua_State*, int, int*);
  87. typedef lua_CFunction (*lua_tocfunction_cdecl_t) (lua_State*, int);
  88. typedef lua_Number (*lua_tonumber_cdecl_t) (lua_State*, int);
  89. typedef lua_Number (*lua_tonumberx_cdecl_t) (lua_State*, int, int*);
  90. typedef void* (*lua_touserdata_cdecl_t) (lua_State*, int);
  91. typedef int (*lua_gettop_cdecl_t) (lua_State*);
  92. typedef int (*lua_load_cdecl_t) (lua_State*, lua_Reader, void*, const char *chunkname);
  93. typedef void (*lua_call_cdecl_t) (lua_State*, int, int);
  94. typedef void (*lua_callk_cdecl_t) (lua_State*, int, int, int, lua_CFunction);
  95. typedef int (*lua_pcall_cdecl_t) (lua_State*, int, int, int);
  96. typedef int (*lua_pcallk_cdecl_t) (lua_State*, int, int, int, int, lua_CFunction);
  97. typedef void (*lua_newtable_cdecl_t) (lua_State*);
  98. typedef void (*lua_createtable_cdecl_t) (lua_State*, int, int);
  99. typedef int (*lua_next_cdecl_t) (lua_State*, int);
  100. typedef int (*lua_rawequal_cdecl_t) (lua_State *L, int idx1, int idx2);
  101. typedef int (*lua_getmetatable_cdecl_t) (lua_State*, int objindex);
  102. typedef int (*lua_setmetatable_cdecl_t) (lua_State*, int objindex);
  103. typedef int (*luaL_ref_cdecl_t) (lua_State *L, int t);
  104. typedef void (*luaL_unref_cdecl_t) (lua_State *L, int t, int ref);
  105. typedef int (*luaL_newmetatable_cdecl_t) (lua_State *L, const char *tname);
  106. typedef int (*luaL_loadbuffer_cdecl_t) (lua_State *L, const char *buff, size_t sz, const char *name);
  107. typedef int (*luaL_loadfile_cdecl_t) (lua_State *L, const char *fileName);
  108. typedef const lua_WChar* (*lua_towstring_cdecl_t) (lua_State *L, int index);
  109. typedef int (*lua_iswstring_cdecl_t) (lua_State *L, int index);
  110. typedef const char* (*lua_getupvalue_cdecl_t) (lua_State *L, int funcindex, int n);
  111. typedef const char* (*lua_setupvalue_cdecl_t) (lua_State *L, int funcindex, int n);
  112. typedef void (*lua_getfenv_cdecl_t) (lua_State *L, int index);
  113. typedef int (*lua_setfenv_cdecl_t) (lua_State *L, int index);
  114. typedef void (*lua_pushlightuserdata_cdecl_t)(lua_State *L, void *p);
  115. typedef int (*lua_cpcall_cdecl_t) (lua_State *L, lua_CFunction func, void *ud);
  116. typedef int (*lua_pushthread_cdecl_t) (lua_State *L);
  117. typedef void * (*lua_newuserdata_cdecl_t) (lua_State *L, size_t size);
  118. typedef lua_State* (*luaL_newstate_cdecl_t) ();
  119. typedef int (*lua_checkstack_cdecl_t) (lua_State* L, int extra);
  120.  
  121. typedef lua_State* (__stdcall *lua_open_stdcall_t) (int stacksize);
  122. typedef lua_State* (__stdcall *lua_open_500_stdcall_t) ();
  123. typedef lua_State* (__stdcall *lua_newstate_stdcall_t) (lua_Alloc, void*);
  124. typedef void (__stdcall *lua_close_stdcall_t) (lua_State*);
  125. typedef lua_State* (__stdcall *lua_newthread_stdcall_t) (lua_State*);
  126. typedef int (__stdcall *lua_error_stdcall_t) (lua_State*);
  127. typedef int (__stdcall *lua_sethook_stdcall_t) (lua_State*, lua_Hook_stdcall, int, int);
  128. typedef int (__stdcall *lua_getinfo_stdcall_t) (lua_State*, const char*, lua_Debug* ar);
  129. typedef void (__stdcall *lua_remove_stdcall_t) (lua_State*, int);
  130. typedef void (__stdcall *lua_settable_stdcall_t) (lua_State*, int);
  131. typedef void (__stdcall *lua_gettable_stdcall_t) (lua_State*, int);
  132. typedef void (__stdcall *lua_rawget_stdcall_t) (lua_State *L, int idx);
  133. typedef void (__stdcall *lua_rawgeti_stdcall_t) (lua_State *L, int idx, int n);
  134. typedef void (__stdcall *lua_rawset_stdcall_t) (lua_State *L, int idx);
  135. typedef void (__stdcall *lua_pushstring_stdcall_t) (lua_State*, const char*);
  136. typedef void (__stdcall *lua_pushlstring_stdcall_t) (lua_State*, const char*, size_t);
  137. typedef int (__stdcall *lua_type_stdcall_t) (lua_State*, int);
  138. typedef const char* (__stdcall *lua_typename_stdcall_t) (lua_State*, int);
  139. typedef void (__stdcall *lua_settop_stdcall_t) (lua_State*, int);
  140. typedef const char* (__stdcall *lua_getlocal_stdcall_t) (lua_State*, const lua_Debug*, int);
  141. typedef const char* (__stdcall *lua_setlocal_stdcall_t) (lua_State*, const lua_Debug*, int);
  142. typedef int (__stdcall *lua_getstack_stdcall_t) (lua_State*, int, lua_Debug*);
  143. typedef void (__stdcall *lua_insert_stdcall_t) (lua_State*, int);
  144. typedef void (__stdcall *lua_pushnil_stdcall_t) (lua_State*);
  145. typedef void (__stdcall *lua_pushcclosure_stdcall_t) (lua_State*, lua_CFunction, int);
  146. typedef void (__stdcall *lua_pushvalue_stdcall_t) (lua_State*, int);
  147. typedef void (__stdcall *lua_pushinteger_stdcall_t) (lua_State*, int);
  148. typedef void (__stdcall *lua_pushnumber_stdcall_t) (lua_State*, lua_Number);
  149. typedef const char* (__stdcall *lua_tostring_stdcall_t) (lua_State*, int);
  150. typedef const char* (__stdcall *lua_tolstring_stdcall_t) (lua_State*, int, size_t*);
  151. typedef int (__stdcall *lua_toboolean_stdcall_t) (lua_State*, int);
  152. typedef int (__stdcall *lua_tointeger_stdcall_t) (lua_State*, int);
  153. typedef lua_Integer (__stdcall *lua_tointegerx_stdcall_t) (lua_State*, int, int*);
  154. typedef lua_CFunction (__stdcall *lua_tocfunction_stdcall_t) (lua_State*, int);
  155. typedef lua_Number (__stdcall *lua_tonumber_stdcall_t) (lua_State*, int);
  156. typedef lua_Number (__stdcall *lua_tonumberx_stdcall_t) (lua_State*, int, int*);
  157. typedef void* (__stdcall *lua_touserdata_stdcall_t) (lua_State*, int);
  158. typedef int (__stdcall *lua_gettop_stdcall_t) (lua_State*);
  159. typedef int (__stdcall *lua_load_stdcall_t) (lua_State*, lua_Reader_stdcall, void*, const char *chunkname);
  160. typedef void (__stdcall *lua_call_stdcall_t) (lua_State*, int, int);
  161. typedef void (__stdcall *lua_callk_stdcall_t) (lua_State*, int, int, int, lua_CFunction);
  162. typedef int (__stdcall *lua_pcall_stdcall_t) (lua_State*, int, int, int);
  163. typedef int (__stdcall *lua_pcallk_stdcall_t) (lua_State*, int, int, int, int, lua_CFunction);
  164. typedef void (__stdcall *lua_newtable_stdcall_t) (lua_State*);
  165. typedef void (__stdcall *lua_createtable_stdcall_t) (lua_State*, int, int);
  166. typedef int (__stdcall *lua_next_stdcall_t) (lua_State*, int);
  167. typedef int (__stdcall *lua_rawequal_stdcall_t) (lua_State *L, int idx1, int idx2);
  168. typedef int (__stdcall *lua_getmetatable_stdcall_t) (lua_State*, int objindex);
  169. typedef int (__stdcall *lua_setmetatable_stdcall_t) (lua_State*, int objindex);
  170. typedef int (__stdcall *luaL_ref_stdcall_t) (lua_State *L, int t);
  171. typedef void (__stdcall *luaL_unref_stdcall_t) (lua_State *L, int t, int ref);
  172. typedef int (__stdcall *luaL_newmetatable_stdcall_t) (lua_State *L, const char *tname);
  173. typedef int (__stdcall *luaL_loadbuffer_stdcall_t) (lua_State *L, const char *buff, size_t sz, const char *name);
  174. typedef int (__stdcall *luaL_loadfile_stdcall_t) (lua_State *L, const char *fileName);
  175. typedef const lua_WChar* (__stdcall *lua_towstring_stdcall_t) (lua_State *L, int index);
  176. typedef int (__stdcall *lua_iswstring_stdcall_t) (lua_State *L, int index);
  177. typedef const char* (__stdcall *lua_getupvalue_stdcall_t) (lua_State *L, int funcindex, int n);
  178. typedef const char* (__stdcall *lua_setupvalue_stdcall_t) (lua_State *L, int funcindex, int n);
  179. typedef void (__stdcall *lua_getfenv_stdcall_t) (lua_State *L, int index);
  180. typedef int (__stdcall *lua_setfenv_stdcall_t) (lua_State *L, int index);
  181. typedef void (__stdcall *lua_pushlightuserdata_stdcall_t)(lua_State *L, void *p);
  182. typedef int (__stdcall *lua_cpcall_stdcall_t) (lua_State *L, lua_CFunction func, void *ud);
  183. typedef int (__stdcall *lua_pushthread_stdcall_t) (lua_State *L);
  184. typedef void * (__stdcall *lua_newuserdata_stdcall_t) (lua_State *L, size_t size);
  185. typedef lua_State* (__stdcall *luaL_newstate_stdcall_t) ();
  186. typedef int (__stdcall *lua_checkstack_stdcall_t) (lua_State* L, int extra);
  187.  
  188. typedef HMODULE (WINAPI *LoadLibraryExW_t) (LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags);
  189. typedef ULONG (WINAPI *LdrLockLoaderLock_t) (ULONG flags, PULONG disposition, PULONG cookie);
  190. typedef LONG (WINAPI *LdrUnlockLoaderLock_t) (ULONG flags, ULONG cookie);
  191.  
  192.  
  193. /**
  194. * Structure that holds pointers to all of the Lua API functions.
  195. */
  196. struct LuaInterface
  197. {
  198.  
  199. int version; // One of 401, 500, 510
  200. bool finishedLoading;
  201.  
  202. bool stdcall;
  203.  
  204. // Use these instead of the LUA_* constants in lua.h. The value of these
  205. // change depending on the version of Lua we're using.
  206. int registryIndex;
  207. int globalsIndex;
  208.  
  209. // cdecl functions.
  210. lua_open_cdecl_t lua_open_dll_cdecl;
  211. lua_open_500_cdecl_t lua_open_500_dll_cdecl;
  212. lua_newstate_cdecl_t lua_newstate_dll_cdecl;
  213. lua_close_cdecl_t lua_close_dll_cdecl;
  214. lua_newthread_cdecl_t lua_newthread_dll_cdecl;
  215. lua_error_cdecl_t lua_error_dll_cdecl;
  216. lua_gettop_cdecl_t lua_gettop_dll_cdecl;
  217. lua_sethook_cdecl_t lua_sethook_dll_cdecl;
  218. lua_getinfo_cdecl_t lua_getinfo_dll_cdecl;
  219. lua_remove_cdecl_t lua_remove_dll_cdecl;
  220. lua_settable_cdecl_t lua_settable_dll_cdecl;
  221. lua_gettable_cdecl_t lua_gettable_dll_cdecl;
  222. lua_rawget_cdecl_t lua_rawget_dll_cdecl;
  223. lua_rawgeti_cdecl_t lua_rawgeti_dll_cdecl;
  224. lua_rawset_cdecl_t lua_rawset_dll_cdecl;
  225. lua_pushstring_cdecl_t lua_pushstring_dll_cdecl;
  226. lua_pushlstring_cdecl_t lua_pushlstring_dll_cdecl;
  227. lua_type_cdecl_t lua_type_dll_cdecl;
  228. lua_typename_cdecl_t lua_typename_dll_cdecl;
  229. lua_settop_cdecl_t lua_settop_dll_cdecl;
  230. lua_getlocal_cdecl_t lua_getlocal_dll_cdecl;
  231. lua_setlocal_cdecl_t lua_setlocal_dll_cdecl;
  232. lua_getstack_cdecl_t lua_getstack_dll_cdecl;
  233. lua_insert_cdecl_t lua_insert_dll_cdecl;
  234. lua_pushnil_cdecl_t lua_pushnil_dll_cdecl;
  235. lua_pushvalue_cdecl_t lua_pushvalue_dll_cdecl;
  236. lua_pushinteger_cdecl_t lua_pushinteger_dll_cdecl;
  237. lua_pushnumber_cdecl_t lua_pushnumber_dll_cdecl;
  238. lua_pushcclosure_cdecl_t lua_pushcclosure_dll_cdecl;
  239. lua_tostring_cdecl_t lua_tostring_dll_cdecl;
  240. lua_tolstring_cdecl_t lua_tolstring_dll_cdecl;
  241. lua_toboolean_cdecl_t lua_toboolean_dll_cdecl;
  242. lua_tointeger_cdecl_t lua_tointeger_dll_cdecl;
  243. lua_tointegerx_cdecl_t lua_tointegerx_dll_cdecl;
  244. lua_tocfunction_cdecl_t lua_tocfunction_dll_cdecl;
  245. lua_tonumber_cdecl_t lua_tonumber_dll_cdecl;
  246. lua_tonumberx_cdecl_t lua_tonumberx_dll_cdecl;
  247. lua_touserdata_cdecl_t lua_touserdata_dll_cdecl;
  248. lua_load_cdecl_t lua_load_dll_cdecl;
  249. lua_call_cdecl_t lua_call_dll_cdecl;
  250. lua_callk_cdecl_t lua_callk_dll_cdecl;
  251. lua_pcall_cdecl_t lua_pcall_dll_cdecl;
  252. lua_pcallk_cdecl_t lua_pcallk_dll_cdecl;
  253. lua_newtable_cdecl_t lua_newtable_dll_cdecl;
  254. lua_createtable_cdecl_t lua_createtable_dll_cdecl;
  255. lua_next_cdecl_t lua_next_dll_cdecl;
  256. lua_rawequal_cdecl_t lua_rawequal_dll_cdecl;
  257. lua_getmetatable_cdecl_t lua_getmetatable_dll_cdecl;
  258. lua_setmetatable_cdecl_t lua_setmetatable_dll_cdecl;
  259. luaL_ref_cdecl_t luaL_ref_dll_cdecl;
  260. luaL_unref_cdecl_t luaL_unref_dll_cdecl;
  261. luaL_newmetatable_cdecl_t luaL_newmetatable_dll_cdecl;
  262. luaL_loadbuffer_cdecl_t luaL_loadbuffer_dll_cdecl;
  263. luaL_loadfile_cdecl_t luaL_loadfile_dll_cdecl;
  264. lua_towstring_cdecl_t lua_towstring_dll_cdecl;
  265. lua_iswstring_cdecl_t lua_iswstring_dll_cdecl;
  266. lua_getupvalue_cdecl_t lua_getupvalue_dll_cdecl;
  267. lua_setupvalue_cdecl_t lua_setupvalue_dll_cdecl;
  268. lua_getfenv_cdecl_t lua_getfenv_dll_cdecl;
  269. lua_setfenv_cdecl_t lua_setfenv_dll_cdecl;
  270. lua_pushlightuserdata_cdecl_t lua_pushlightuserdata_dll_cdecl;
  271. lua_cpcall_cdecl_t lua_cpcall_dll_cdecl;
  272. lua_pushthread_cdecl_t lua_pushthread_dll_cdecl;
  273. lua_newuserdata_cdecl_t lua_newuserdata_dll_cdecl;
  274. luaL_newstate_cdecl_t luaL_newstate_dll_cdecl;
  275. lua_checkstack_cdecl_t lua_checkstack_dll_cdecl;
  276.  
  277. // stdcall functions.
  278. lua_open_stdcall_t lua_open_dll_stdcall;
  279. lua_open_500_stdcall_t lua_open_500_dll_stdcall;
  280. lua_newstate_stdcall_t lua_newstate_dll_stdcall;
  281. lua_close_stdcall_t lua_close_dll_stdcall;
  282. lua_newthread_stdcall_t lua_newthread_dll_stdcall;
  283. lua_error_stdcall_t lua_error_dll_stdcall;
  284. lua_gettop_stdcall_t lua_gettop_dll_stdcall;
  285. lua_sethook_stdcall_t lua_sethook_dll_stdcall;
  286. lua_getinfo_stdcall_t lua_getinfo_dll_stdcall;
  287. lua_remove_stdcall_t lua_remove_dll_stdcall;
  288. lua_settable_stdcall_t lua_settable_dll_stdcall;
  289. lua_gettable_stdcall_t lua_gettable_dll_stdcall;
  290. lua_rawget_stdcall_t lua_rawget_dll_stdcall;
  291. lua_rawgeti_stdcall_t lua_rawgeti_dll_stdcall;
  292. lua_rawset_stdcall_t lua_rawset_dll_stdcall;
  293. lua_pushstring_stdcall_t lua_pushstring_dll_stdcall;
  294. lua_pushlstring_stdcall_t lua_pushlstring_dll_stdcall;
  295. lua_type_stdcall_t lua_type_dll_stdcall;
  296. lua_typename_stdcall_t lua_typename_dll_stdcall;
  297. lua_settop_stdcall_t lua_settop_dll_stdcall;
  298. lua_getlocal_stdcall_t lua_getlocal_dll_stdcall;
  299. lua_setlocal_stdcall_t lua_setlocal_dll_stdcall;
  300. lua_getstack_stdcall_t lua_getstack_dll_stdcall;
  301. lua_insert_stdcall_t lua_insert_dll_stdcall;
  302. lua_pushnil_stdcall_t lua_pushnil_dll_stdcall;
  303. lua_pushvalue_stdcall_t lua_pushvalue_dll_stdcall;
  304. lua_pushinteger_stdcall_t lua_pushinteger_dll_stdcall;
  305. lua_pushnumber_stdcall_t lua_pushnumber_dll_stdcall;
  306. lua_pushcclosure_stdcall_t lua_pushcclosure_dll_stdcall;
  307. lua_tostring_stdcall_t lua_tostring_dll_stdcall;
  308. lua_tolstring_stdcall_t lua_tolstring_dll_stdcall;
  309. lua_toboolean_stdcall_t lua_toboolean_dll_stdcall;
  310. lua_tointeger_stdcall_t lua_tointeger_dll_stdcall;
  311. lua_tointegerx_stdcall_t lua_tointegerx_dll_stdcall;
  312. lua_tocfunction_stdcall_t lua_tocfunction_dll_stdcall;
  313. lua_tonumber_stdcall_t lua_tonumber_dll_stdcall;
  314. lua_tonumberx_stdcall_t lua_tonumberx_dll_stdcall;
  315. lua_touserdata_stdcall_t lua_touserdata_dll_stdcall;
  316. lua_load_stdcall_t lua_load_dll_stdcall;
  317. lua_call_stdcall_t lua_call_dll_stdcall;
  318. lua_callk_stdcall_t lua_callk_dll_stdcall;
  319. lua_pcall_stdcall_t lua_pcall_dll_stdcall;
  320. lua_pcallk_stdcall_t lua_pcallk_dll_stdcall;
  321. lua_newtable_stdcall_t lua_newtable_dll_stdcall;
  322. lua_createtable_stdcall_t lua_createtable_dll_stdcall;
  323. lua_next_stdcall_t lua_next_dll_stdcall;
  324. lua_rawequal_stdcall_t lua_rawequal_dll_stdcall;
  325. lua_getmetatable_stdcall_t lua_getmetatable_dll_stdcall;
  326. lua_setmetatable_stdcall_t lua_setmetatable_dll_stdcall;
  327. luaL_ref_stdcall_t luaL_ref_dll_stdcall;
  328. luaL_unref_stdcall_t luaL_unref_dll_stdcall;
  329. luaL_newmetatable_stdcall_t luaL_newmetatable_dll_stdcall;
  330. luaL_loadbuffer_stdcall_t luaL_loadbuffer_dll_stdcall;
  331. luaL_loadfile_stdcall_t luaL_loadfile_dll_stdcall;
  332. lua_towstring_stdcall_t lua_towstring_dll_stdcall;
  333. lua_iswstring_stdcall_t lua_iswstring_dll_stdcall;
  334. lua_getupvalue_stdcall_t lua_getupvalue_dll_stdcall;
  335. lua_setupvalue_stdcall_t lua_setupvalue_dll_stdcall;
  336. lua_getfenv_stdcall_t lua_getfenv_dll_stdcall;
  337. lua_setfenv_stdcall_t lua_setfenv_dll_stdcall;
  338. lua_pushlightuserdata_stdcall_t lua_pushlightuserdata_dll_stdcall;
  339. lua_cpcall_stdcall_t lua_cpcall_dll_stdcall;
  340. lua_pushthread_stdcall_t lua_pushthread_dll_stdcall;
  341. lua_newuserdata_stdcall_t lua_newuserdata_dll_stdcall;
  342. luaL_newstate_stdcall_t luaL_newstate_dll_stdcall;
  343. lua_checkstack_stdcall_t lua_checkstack_dll_stdcall;
  344.  
  345. lua_CFunction DecodaOutput;
  346. lua_CFunction CPCallHandler;
  347. lua_Hook HookHandler;
  348.  
  349. };
  350.  
  351. struct CPCallHandlerArgs
  352. {
  353. lua_CFunction_dll function;
  354. void* data;
  355. };
  356.  
  357. /**
  358. * This macro outputs the prolog code for a naked intercept function. It
  359. * should be the first code in the function.
  360. */
  361. #define INTERCEPT_PROLOG() \
  362.  
  363. extern "C"
  364. {
  365. void intprolog ();
  366. }
  367. /*
  368. __asm \
  369. { \
  370. __asm push ebp \
  371. __asm mov ebp, esp \
  372. __asm sub esp, __LOCAL_SIZE \
  373. }
  374. */
  375.  
  376.  
  377. /**
  378. * This macro outputs the epilog code for a naked intercept function. It
  379. * should be the last code in the function. argsSize is the number of
  380. * bytes for the argments to the function (not including the the api parameter).
  381. * The return from the function should be stored in the "result" variable, and
  382. * the "stdcall" bool variable determines if the function was called using the
  383. * stdcall or cdecl calling convention.
  384. */
  385. #define INTERCEPT_EPILOG(argsSize) \
  386. __asm \
  387. { \
  388. __asm mov eax, result \
  389. __asm cmp stdcall, 0 \
  390. __asm mov esp, ebp \
  391. __asm pop ebp \
  392. __asm jne stdcall_ret \
  393. __asm ret 4 \
  394. __asm stdcall_ret: \
  395. __asm ret (4 + argsSize) \
  396. }
  397.  
  398. /**
  399. * This macro outputs the epilog code for a naked intercept function that doesn't
  400. * have a return value. It should be the last code in the function. argsSize is the
  401. * number of bytes for the argments to the function (not including the the api
  402. * parameter). The "stdcall" bool variable determines if the function was called using
  403. * the stdcall or cdecl calling convention.
  404. */
  405. #define INTERCEPT_EPILOG_NO_RETURN(argsSize) \
  406. __asm \
  407. { \
  408. __asm cmp stdcall, 0 \
  409. __asm mov esp, ebp \
  410. __asm pop ebp \
  411. __asm jne stdcall_ret \
  412. __asm ret 4 \
  413. __asm stdcall_ret: \
  414. __asm ret (4 + argsSize) \
  415. }
  416.  
  417.  
  418. LoadLibraryExW_t LoadLibraryExW_dll = NULL;
  419. LdrLockLoaderLock_t LdrLockLoaderLock_dll = NULL;
  420. LdrUnlockLoaderLock_t LdrUnlockLoaderLock_dll = NULL;
  421.  
  422. bool g_loadedLuaFunctions = false;
  423. std::set<std::string> g_loadedModules;
  424. CriticalSection g_loadedModulesCriticalSection;
  425.  
  426. std::vector<LuaInterface> g_interfaces;
  427. stdext::hash_map<void*, void*> g_hookedFunctionMap;
  428.  
  429. stdext::hash_set<std::string> g_warnedAboutLua; // Indivates that we've warned the module contains Lua functions but none were loaded.
  430. stdext::hash_set<std::string> g_warnedAboutPdb; // Indicates that we've warned about a module having a mismatched PDB.
  431. bool g_warnedAboutThreads = false;
  432. bool g_warnedAboutJit = false;
  433.  
  434. std::string g_symbolsDirectory;
  435. static DWORD g_disableInterceptIndex = 0;
  436. bool g_initializedDebugHelp = false;
  437.  
  438. /**
  439. * Function called after a library has been loaded by the host application.
  440. * We use this to check for the Lua dll.
  441. */
  442. void PostLoadLibrary(HMODULE hModule);
  443.  
  444. /**
  445. * Data structure passed into the MemoryReader function.
  446. */
  447. struct Memory
  448. {
  449. const char* buffer;
  450. size_t size;
  451. };
  452.  
  453. /**
  454. * lua_Reader function used to read from a memory buffer.
  455. */
  456. const char* MemoryReader_cdecl(lua_State* L, void* data, size_t* size)
  457. {
  458.  
  459. Memory* memory = static_cast<Memory*>(data);
  460.  
  461. if (memory->size > 0)
  462. {
  463. *size = memory->size;
  464. memory->size = 0;
  465. return memory->buffer;
  466. }
  467. else
  468. {
  469. return NULL;
  470. }
  471.  
  472. }
  473.  
  474. /**
  475. * lua_Reader function used to read from a memory buffer.
  476. */
  477. const char* __stdcall MemoryReader_stdcall(lua_State* L, void* data, size_t* size)
  478. {
  479.  
  480. Memory* memory = static_cast<Memory*>(data);
  481.  
  482. if (memory->size > 0)
  483. {
  484. *size = memory->size;
  485. memory->size = 0;
  486. return memory->buffer;
  487. }
  488. else
  489. {
  490. return NULL;
  491. }
  492.  
  493. }
  494.  
  495. #pragma auto_inline(off)
  496. int DecodaOutputWorker(unsigned long api, lua_State* L, bool& stdcall)
  497. {
  498.  
  499. stdcall = g_interfaces[api].stdcall;
  500.  
  501. const char* message = lua_tostring_dll(api, L, 1);
  502. DebugBackend::Get().Message(message);
  503.  
  504. return 0;
  505.  
  506. }
  507. #pragma auto_inline()
  508.  
  509. __declspec(naked) int DecodaOutput(unsigned long api, lua_State* L)
  510. {
  511.  
  512. int result;
  513. bool stdcall;
  514.  
  515. INTERCEPT_PROLOG()
  516.  
  517. result = DecodaOutputWorker(api, L, stdcall);
  518.  
  519. INTERCEPT_EPILOG(4)
  520.  
  521. }
  522.  
  523. #pragma auto_inline(off)
  524. int CPCallHandlerWorker(unsigned long api, lua_State* L, bool& stdcall)
  525. {
  526.  
  527. stdcall = g_interfaces[api].stdcall;
  528. CPCallHandlerArgs args = *static_cast<CPCallHandlerArgs*>(lua_touserdata_dll(api, L, 1));
  529.  
  530. // Remove the old args and put the new one on the stack.
  531. lua_pop_dll(api, L, 1);
  532. lua_pushlightuserdata_dll(api, L, args.data);
  533.  
  534. return args.function(api, L);
  535.  
  536. }
  537. #pragma auto_inline()
  538.  
  539. __declspec(naked) int CPCallHandler(unsigned long api, lua_State* L)
  540. {
  541.  
  542. int result;
  543. bool stdcall;
  544.  
  545. INTERCEPT_PROLOG()
  546.  
  547. result = CPCallHandlerWorker(api, L, stdcall);
  548.  
  549. INTERCEPT_EPILOG(4)
  550.  
  551. }
  552.  
  553. int lua_cpcall_dll(unsigned long api, lua_State *L, lua_CFunction_dll func, void *udn)
  554. {
  555.  
  556. CPCallHandlerArgs args;
  557.  
  558. args.function = func;
  559. args.data = udn;
  560.  
  561. return lua_cpcall_dll(api, L, g_interfaces[api].CPCallHandler, &args);
  562.  
  563. }
  564.  
  565. #pragma auto_inline(off)
  566. void HookHandlerWorker(unsigned long api, lua_State* L, lua_Debug* ar, bool& stdcall)
  567. {
  568. stdcall = g_interfaces[api].stdcall;
  569. return DebugBackend::Get().HookCallback(api, L, ar);
  570. }
  571. #pragma auto_inline()
  572.  
  573. __declspec(naked) void HookHandler(unsigned long api, lua_State* L, lua_Debug* ar)
  574. {
  575.  
  576. bool stdcall;
  577.  
  578. INTERCEPT_PROLOG()
  579.  
  580. HookHandlerWorker(api, L, ar, stdcall);
  581.  
  582. INTERCEPT_EPILOG_NO_RETURN(8)
  583.  
  584. }
  585.  
  586. void SetHookEnabled(unsigned long api, lua_State* L, bool hookEnabled)
  587. {
  588. if (hookEnabled)
  589. {
  590. lua_sethook_dll(api, L, g_interfaces[api].HookHandler, LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE, 0);
  591. }
  592. else
  593. {
  594. lua_sethook_dll(api, L, g_interfaces[api].HookHandler, 0, 0);
  595. }
  596. }
  597.  
  598. bool lua_pushthread_dll(unsigned long api, lua_State *L)
  599. {
  600.  
  601. // These structures are taken out of the Lua 5.0 source code.
  602.  
  603. union lua_Value_500
  604. {
  605. void* gc;
  606. void* p;
  607. lua_Number n;
  608. int b;
  609. };
  610.  
  611. struct lua_TObject_500
  612. {
  613. int tt;
  614. lua_Value_500 value;
  615. };
  616.  
  617. struct lua_State_500
  618. {
  619. void* next;
  620. unsigned char tt;
  621. unsigned char marked;
  622. lua_TObject_500* top;
  623. };
  624.  
  625. #pragma pack(1)
  626.  
  627. union lua_Value_500_pack1
  628. {
  629. void* gc;
  630. void* p;
  631. lua_Number n;
  632. int b;
  633. };
  634.  
  635. struct lua_TObject_500_pack1
  636. {
  637. int tt;
  638. lua_Value_500_pack1 value;
  639. };
  640.  
  641. struct lua_State_500_pack1
  642. {
  643. void* next;
  644. unsigned char tt;
  645. unsigned char marked;
  646. lua_TObject_500_pack1* top;
  647. };
  648.  
  649. #pragma pack()
  650.  
  651. if (g_interfaces[api].lua_pushthread_dll_cdecl != NULL)
  652. {
  653. g_interfaces[api].lua_pushthread_dll_cdecl(L);
  654. return true;
  655. }
  656. else if (g_interfaces[api].lua_pushthread_dll_stdcall != NULL)
  657. {
  658. g_interfaces[api].lua_pushthread_dll_stdcall(L);
  659. return true;
  660. }
  661. else
  662. {
  663.  
  664. // The actual push thread function doesn't exist (probably Lua 5.0), so
  665. // emulate it. The lua_pushthread function just pushes the state onto the
  666. // stack and sets the type to LUA_TTHREAD. We use the pushlightuserdata
  667. // function which basically does the same thing, except we need to modify the
  668. // type of the object on the top of the stack.
  669.  
  670. lua_pushlightuserdata_dll(api, L, L);
  671.  
  672. // Check that the thing we think is pointing to the top of the stack actually
  673. // is so that we don't overwrite something in memory.
  674.  
  675. bool success = false;
  676.  
  677. // If the structures are laid out differently in the implementation of Lua
  678. // we might get crashes, so we wrap the access in a try block.
  679.  
  680. __try
  681. {
  682. lua_State_500* S = reinterpret_cast<lua_State_500*>(L);
  683. lua_TObject_500* top = S->top - 1;
  684. if (top->tt == LUA_TLIGHTUSERDATA && top->value.p == L)
  685. {
  686. top->tt = LUA_TTHREAD;
  687. top->value.gc = L;
  688. success = true;
  689. }
  690. }
  691. __except (EXCEPTION_EXECUTE_HANDLER)
  692. {
  693. }
  694.  
  695. if (!success)
  696. {
  697. // The unpacked version didn't work out right, so try the version with no alignment.
  698. __try
  699. {
  700. lua_State_500_pack1* S = reinterpret_cast<lua_State_500_pack1*>(L);
  701. lua_TObject_500_pack1* top = S->top - 1;
  702. if (top->tt == LUA_TLIGHTUSERDATA && top->value.p == L)
  703. {
  704. top->tt = LUA_TTHREAD;
  705. top->value.gc = L;
  706. success = true;
  707. }
  708. }
  709. __except (EXCEPTION_EXECUTE_HANDLER)
  710. {
  711. }
  712. }
  713.  
  714. if (!success)
  715. {
  716. lua_pop_dll(api, L, 1);
  717. if (!g_warnedAboutThreads)
  718. {
  719. DebugBackend::Get().Message("Warning 1006: lua_pushthread could not be emulated due to modifications to Lua. Coroutines may be unstable", MessageType_Warning);
  720. g_warnedAboutThreads = true;
  721. }
  722. }
  723.  
  724. return success;
  725.  
  726. }
  727.  
  728. }
  729.  
  730. void* lua_newuserdata_dll(unsigned long api, lua_State *L, size_t size)
  731. {
  732. if (g_interfaces[api].lua_newuserdata_dll_cdecl != NULL)
  733. {
  734. return g_interfaces[api].lua_newuserdata_dll_cdecl(L, size);
  735. }
  736. else
  737. {
  738. return g_interfaces[api].lua_newuserdata_dll_stdcall(L, size);
  739. }
  740. }
  741.  
  742. void EnableIntercepts(bool enableIntercepts)
  743. {
  744. int value = reinterpret_cast<int>(TlsGetValue(g_disableInterceptIndex));
  745. if (enableIntercepts)
  746. {
  747. --value;
  748. }
  749. else
  750. {
  751. ++value;
  752. }
  753. TlsSetValue(g_disableInterceptIndex, reinterpret_cast<LPVOID>(value));
  754. }
  755.  
  756. bool GetAreInterceptsEnabled()
  757. {
  758. int value = reinterpret_cast<int>(TlsGetValue(g_disableInterceptIndex));
  759. return value <= 0;
  760. }
  761.  
  762. void RegisterDebugLibrary(unsigned long api, lua_State* L)
  763. {
  764. lua_register_dll(api, L, "decoda_output", g_interfaces[api].DecodaOutput);
  765. }
  766.  
  767. int GetGlobalsIndex(unsigned long api)
  768. {
  769. return g_interfaces[api].globalsIndex;
  770. }
  771.  
  772. int GetRegistryIndex(unsigned long api)
  773. {
  774. return g_interfaces[api].registryIndex;
  775. }
  776.  
  777. int lua_abs_index_dll(unsigned long api, lua_State* L, int i)
  778. {
  779. if (i > 0 || i <= GetRegistryIndex(api))
  780. {
  781. return i;
  782. }
  783. else
  784. {
  785. return lua_gettop_dll(api, L) + i + 1;
  786. }
  787. }
  788.  
  789. int lua_upvalueindex_dll(unsigned long api, int i)
  790. {
  791. return GetGlobalsIndex(api) - i;
  792. }
  793.  
  794. void lua_setglobal_dll(unsigned long api, lua_State* L, const char* s)
  795. {
  796. lua_setfield_dll(api, L, GetGlobalsIndex(api), s);
  797. }
  798.  
  799. void lua_getglobal_dll(unsigned long api, lua_State* L, const char* s)
  800. {
  801. lua_getfield_dll(api, L, GetGlobalsIndex(api), s);
  802. }
  803.  
  804. void lua_rawgetglobal_dll(unsigned long api, lua_State* L, const char* s)
  805. {
  806. lua_pushstring_dll(api, L, s);
  807. lua_rawget_dll(api, L, GetGlobalsIndex(api));
  808. }
  809.  
  810. lua_State* lua_newstate_dll(unsigned long api, lua_Alloc f, void* ud)
  811. {
  812. if (g_interfaces[api].lua_newstate_dll_cdecl != NULL)
  813. {
  814. return g_interfaces[api].lua_newstate_dll_cdecl(f, ud);
  815. }
  816. else if (g_interfaces[api].lua_newstate_dll_stdcall != NULL)
  817. {
  818. return g_interfaces[api].lua_newstate_dll_stdcall(f, ud);
  819. }
  820.  
  821. // This is an older version of Lua that doesn't support lua_newstate, so emulate it
  822. // with lua_open.
  823.  
  824. if (g_interfaces[api].lua_open_500_dll_cdecl != NULL)
  825. {
  826. return g_interfaces[api].lua_open_500_dll_cdecl();
  827. }
  828. else if (g_interfaces[api].lua_open_500_dll_stdcall != NULL)
  829. {
  830. return g_interfaces[api].lua_open_500_dll_stdcall();
  831. }
  832. else if (g_interfaces[api].lua_open_dll_cdecl != NULL)
  833. {
  834. return g_interfaces[api].lua_open_dll_cdecl(0);
  835. }
  836. else if (g_interfaces[api].lua_open_dll_stdcall != NULL)
  837. {
  838. return g_interfaces[api].lua_open_dll_stdcall(0);
  839. }
  840.  
  841. assert(0);
  842. return NULL;
  843.  
  844. }
  845.  
  846. void lua_close_dll(unsigned long api, lua_State* L)
  847. {
  848. if (g_interfaces[api].lua_close_dll_cdecl != NULL)
  849. {
  850. g_interfaces[api].lua_close_dll_cdecl(L);
  851. }
  852. else
  853. {
  854. g_interfaces[api].lua_close_dll_stdcall(L);
  855. }
  856. }
  857.  
  858. lua_State* lua_newthread_dll(unsigned long api, lua_State* L)
  859. {
  860. if (g_interfaces[api].lua_newthread_dll_cdecl != NULL)
  861. {
  862. return g_interfaces[api].lua_newthread_dll_cdecl(L);
  863. }
  864. else
  865. {
  866. return g_interfaces[api].lua_newthread_dll_stdcall(L);
  867. }
  868. }
  869.  
  870. int lua_error_dll(unsigned long api, lua_State* L)
  871. {
  872. if (g_interfaces[api].lua_error_dll_cdecl != NULL)
  873. {
  874. return g_interfaces[api].lua_error_dll_cdecl(L);
  875. }
  876. else
  877. {
  878. return g_interfaces[api].lua_error_dll_stdcall(L);
  879. }
  880. }
  881.  
  882. int lua_sethook_dll(unsigned long api, lua_State* L, lua_Hook f, int mask, int count)
  883. {
  884. if (g_interfaces[api].lua_sethook_dll_cdecl != NULL)
  885. {
  886. return g_interfaces[api].lua_sethook_dll_cdecl(L, f, mask, count);
  887. }
  888. else
  889. {
  890. return g_interfaces[api].lua_sethook_dll_stdcall(L, (lua_Hook_stdcall)f, mask, count);
  891. }
  892. }
  893.  
  894. int lua_getinfo_dll(unsigned long api, lua_State* L, const char* what, lua_Debug* ar)
  895. {
  896. if (g_interfaces[api].lua_getinfo_dll_cdecl != NULL)
  897. {
  898. return g_interfaces[api].lua_getinfo_dll_cdecl(L, what, ar);
  899. }
  900. else
  901. {
  902. return g_interfaces[api].lua_getinfo_dll_stdcall(L, what, ar);
  903. }
  904. }
  905.  
  906. void lua_remove_dll(unsigned long api, lua_State* L, int index)
  907. {
  908. if (g_interfaces[api].lua_remove_dll_cdecl != NULL)
  909. {
  910. g_interfaces[api].lua_remove_dll_cdecl(L, index);
  911. }
  912. else
  913. {
  914. g_interfaces[api].lua_remove_dll_stdcall(L, index);
  915. }
  916. }
  917.  
  918. void lua_settable_dll(unsigned long api, lua_State* L, int index)
  919. {
  920. if (g_interfaces[api].lua_settable_dll_cdecl != NULL)
  921. {
  922. g_interfaces[api].lua_settable_dll_cdecl(L, index);
  923. }
  924. else
  925. {
  926. g_interfaces[api].lua_settable_dll_stdcall(L, index);
  927. }
  928. }
  929.  
  930. void lua_gettable_dll(unsigned long api, lua_State* L, int index)
  931. {
  932. if (g_interfaces[api].lua_gettable_dll_cdecl != NULL)
  933. {
  934. g_interfaces[api].lua_gettable_dll_cdecl(L, index);
  935. }
  936. else
  937. {
  938. g_interfaces[api].lua_gettable_dll_stdcall(L, index);
  939. }
  940. }
  941.  
  942. void lua_rawget_dll(unsigned long api, lua_State* L, int idx)
  943. {
  944. if (g_interfaces[api].lua_rawget_dll_cdecl != NULL)
  945. {
  946. g_interfaces[api].lua_rawget_dll_cdecl(L, idx);
  947. }
  948. else
  949. {
  950. g_interfaces[api].lua_rawget_dll_stdcall(L, idx);
  951. }
  952. }
  953.  
  954. void lua_rawgeti_dll(unsigned long api, lua_State *L, int idx, int n)
  955. {
  956. if (g_interfaces[api].lua_rawgeti_dll_cdecl != NULL)
  957. {
  958. g_interfaces[api].lua_rawgeti_dll_cdecl(L, idx, n);
  959. }
  960. else
  961. {
  962. g_interfaces[api].lua_rawgeti_dll_stdcall(L, idx, n);
  963. }
  964. }
  965.  
  966. void lua_rawset_dll(unsigned long api, lua_State* L, int idx)
  967. {
  968. if (g_interfaces[api].lua_rawset_dll_cdecl != NULL)
  969. {
  970. g_interfaces[api].lua_rawset_dll_cdecl(L, idx);
  971. }
  972. else
  973. {
  974. g_interfaces[api].lua_rawset_dll_stdcall(L, idx);
  975. }
  976. }
  977.  
  978. void lua_pushstring_dll(unsigned long api, lua_State* L, const char* s)
  979. {
  980. if (g_interfaces[api].lua_pushstring_dll_cdecl != NULL)
  981. {
  982. g_interfaces[api].lua_pushstring_dll_cdecl(L, s);
  983. }
  984. else
  985. {
  986. g_interfaces[api].lua_pushstring_dll_stdcall(L, s);
  987. }
  988. }
  989.  
  990. void lua_pushlstring_dll(unsigned long api, lua_State* L, const char* s, size_t len)
  991. {
  992. if (g_interfaces[api].lua_pushlstring_dll_cdecl != NULL)
  993. {
  994. g_interfaces[api].lua_pushlstring_dll_cdecl(L, s, len);
  995. }
  996. else
  997. {
  998. g_interfaces[api].lua_pushlstring_dll_stdcall(L, s, len);
  999. }
  1000. }
  1001.  
  1002. int lua_type_dll(unsigned long api, lua_State* L, int index)
  1003. {
  1004. if (g_interfaces[api].lua_type_dll_cdecl != NULL)
  1005. {
  1006. return g_interfaces[api].lua_type_dll_cdecl(L, index);
  1007. }
  1008. else
  1009. {
  1010. return g_interfaces[api].lua_type_dll_stdcall(L, index);
  1011. }
  1012. }
  1013.  
  1014. const char* lua_typename_dll(unsigned long api, lua_State* L, int type)
  1015. {
  1016. if (g_interfaces[api].lua_typename_dll_cdecl != NULL)
  1017. {
  1018. return g_interfaces[api].lua_typename_dll_cdecl(L, type);
  1019. }
  1020. else
  1021. {
  1022. return g_interfaces[api].lua_typename_dll_stdcall(L, type);
  1023. }
  1024. }
  1025.  
  1026. int lua_checkstack_dll(unsigned long api, lua_State* L, int extra)
  1027. {
  1028. if (g_interfaces[api].lua_checkstack_dll_cdecl != NULL)
  1029. {
  1030. return g_interfaces[api].lua_checkstack_dll_cdecl(L, extra);
  1031. }
  1032. else
  1033. {
  1034. return g_interfaces[api].lua_checkstack_dll_stdcall(L, extra);
  1035. }
  1036. }
  1037.  
  1038. void lua_getfield_dll(unsigned long api, lua_State* L, int index, const char* k)
  1039. {
  1040.  
  1041. // Since Lua 4.0 doesn't include lua_getfield, we just emulate its
  1042. // behavior for simplicity.
  1043.  
  1044. index = lua_abs_index_dll(api, L, index);
  1045.  
  1046. lua_pushstring_dll(api, L, k);
  1047. lua_gettable_dll(api, L, index);
  1048.  
  1049. }
  1050.  
  1051. void lua_setfield_dll(unsigned long api, lua_State* L, int index, const char* k)
  1052. {
  1053.  
  1054. // Since Lua 4.0 doesn't include lua_setfield, we just emulate its
  1055. // behavior for simplicity.
  1056.  
  1057. index = lua_abs_index_dll(api, L, index);
  1058.  
  1059. lua_pushstring_dll(api, L, k);
  1060. lua_insert_dll(api, L, -2);
  1061. lua_settable_dll(api, L, index);
  1062.  
  1063. }
  1064.  
  1065. void lua_settop_dll(unsigned long api, lua_State* L, int index)
  1066. {
  1067. if (g_interfaces[api].lua_settop_dll_cdecl != NULL)
  1068. {
  1069. g_interfaces[api].lua_settop_dll_cdecl(L, index);
  1070. }
  1071. else
  1072. {
  1073. g_interfaces[api].lua_settop_dll_stdcall(L, index);
  1074. }
  1075. }
  1076.  
  1077. const char* lua_getlocal_dll(unsigned long api, lua_State* L, const lua_Debug* ar, int n)
  1078. {
  1079. if (g_interfaces[api].lua_getlocal_dll_cdecl != NULL)
  1080. {
  1081. return g_interfaces[api].lua_getlocal_dll_cdecl(L, ar, n);
  1082. }
  1083. else
  1084. {
  1085. return g_interfaces[api].lua_getlocal_dll_stdcall(L, ar, n);
  1086. }
  1087. }
  1088.  
  1089. const char* lua_setlocal_dll(unsigned long api, lua_State* L, const lua_Debug* ar, int n)
  1090. {
  1091. if (g_interfaces[api].lua_setlocal_dll_cdecl != NULL)
  1092. {
  1093. return g_interfaces[api].lua_setlocal_dll_cdecl(L, ar, n);
  1094. }
  1095. else
  1096. {
  1097. return g_interfaces[api].lua_setlocal_dll_stdcall(L, ar, n);
  1098. }
  1099. }
  1100.  
  1101. int lua_getstack_dll(unsigned long api, lua_State* L, int level, lua_Debug* ar)
  1102. {
  1103. if (g_interfaces[api].lua_getstack_dll_cdecl != NULL)
  1104. {
  1105. return g_interfaces[api].lua_getstack_dll_cdecl(L, level, ar);
  1106. }
  1107. else
  1108. {
  1109. return g_interfaces[api].lua_getstack_dll_stdcall(L, level, ar);
  1110. }
  1111. }
  1112.  
  1113. void lua_insert_dll(unsigned long api, lua_State* L, int index)
  1114. {
  1115. if (g_interfaces[api].lua_insert_dll_cdecl != NULL)
  1116. {
  1117. g_interfaces[api].lua_insert_dll_cdecl(L, index);
  1118. }
  1119. else
  1120. {
  1121. g_interfaces[api].lua_insert_dll_stdcall(L, index);
  1122. }
  1123. }
  1124.  
  1125. void lua_pushnil_dll(unsigned long api, lua_State* L)
  1126. {
  1127. if (g_interfaces[api].lua_pushnil_dll_cdecl != NULL)
  1128. {
  1129. g_interfaces[api].lua_pushnil_dll_cdecl(L);
  1130. }
  1131. else
  1132. {
  1133. g_interfaces[api].lua_pushnil_dll_stdcall(L);
  1134. }
  1135. }
  1136.  
  1137. void lua_pushcclosure_dll(unsigned long api, lua_State* L, lua_CFunction fn, int n)
  1138. {
  1139. if (g_interfaces[api].lua_pushcclosure_dll_cdecl != NULL)
  1140. {
  1141. g_interfaces[api].lua_pushcclosure_dll_cdecl(L, fn, n);
  1142. }
  1143. else
  1144. {
  1145. g_interfaces[api].lua_pushcclosure_dll_stdcall(L, fn, n);
  1146. }
  1147. }
  1148.  
  1149. void lua_pushvalue_dll(unsigned long api, lua_State* L, int index)
  1150. {
  1151. if (g_interfaces[api].lua_pushvalue_dll_cdecl != NULL)
  1152. {
  1153. g_interfaces[api].lua_pushvalue_dll_cdecl(L, index);
  1154. }
  1155. else
  1156. {
  1157. g_interfaces[api].lua_pushvalue_dll_stdcall(L, index);
  1158. }
  1159. }
  1160.  
  1161. void lua_pushnumber_dll(unsigned long api, lua_State* L, lua_Number value)
  1162. {
  1163. if (g_interfaces[api].lua_pushnumber_dll_cdecl != NULL)
  1164. {
  1165. g_interfaces[api].lua_pushnumber_dll_cdecl(L, value);
  1166. }
  1167. else
  1168. {
  1169. g_interfaces[api].lua_pushnumber_dll_stdcall(L, value);
  1170. }
  1171. }
  1172.  
  1173. void lua_pushinteger_dll(unsigned long api, lua_State* L, int value)
  1174. {
  1175. if (g_interfaces[api].lua_pushinteger_dll_cdecl != NULL ||
  1176. g_interfaces[api].lua_pushinteger_dll_stdcall != NULL)
  1177. {
  1178. // Lua 5.0 version.
  1179. if (g_interfaces[api].lua_pushinteger_dll_cdecl != NULL)
  1180. {
  1181. return g_interfaces[api].lua_pushinteger_dll_cdecl(L, value);
  1182. }
  1183. else
  1184. {
  1185. return g_interfaces[api].lua_pushinteger_dll_stdcall(L, value);
  1186. }
  1187. }
  1188. else
  1189. {
  1190. // Fallback to lua_pushnumber on Lua 4.0.
  1191. lua_pushnumber_dll(api, L, static_cast<lua_Number>(value));
  1192. }
  1193. }
  1194.  
  1195. void lua_pushlightuserdata_dll(unsigned long api, lua_State* L, void* p)
  1196. {
  1197. if (g_interfaces[api].lua_pushlightuserdata_dll_cdecl != NULL)
  1198. {
  1199. g_interfaces[api].lua_pushlightuserdata_dll_cdecl(L, p);
  1200. }
  1201. else
  1202. {
  1203. g_interfaces[api].lua_pushlightuserdata_dll_stdcall(L, p);
  1204. }
  1205. }
  1206.  
  1207. const char* lua_tostring_dll(unsigned long api, lua_State* L, int index)
  1208. {
  1209. if (g_interfaces[api].lua_tostring_dll_cdecl != NULL ||
  1210. g_interfaces[api].lua_tostring_dll_stdcall != NULL)
  1211. {
  1212. // Lua 4.0 implementation.
  1213. if (g_interfaces[api].lua_tostring_dll_cdecl != NULL)
  1214. {
  1215. return g_interfaces[api].lua_tostring_dll_cdecl(L, index);
  1216. }
  1217. else
  1218. {
  1219. return g_interfaces[api].lua_tostring_dll_stdcall(L, index);
  1220. }
  1221. }
  1222. else
  1223. {
  1224. // Lua 5.0 version.
  1225. if (g_interfaces[api].lua_tolstring_dll_cdecl != NULL)
  1226. {
  1227. return g_interfaces[api].lua_tolstring_dll_cdecl(L, index, NULL);
  1228. }
  1229. else
  1230. {
  1231. return g_interfaces[api].lua_tolstring_dll_stdcall(L, index, NULL);
  1232. }
  1233. }
  1234. }
  1235.  
  1236. const char* lua_tolstring_dll(unsigned long api, lua_State* L, int index, size_t* len)
  1237. {
  1238. if (g_interfaces[api].lua_tolstring_dll_cdecl != NULL ||
  1239. g_interfaces[api].lua_tolstring_dll_stdcall != NULL)
  1240. {
  1241. // Lua 5.0 version.
  1242. if (g_interfaces[api].lua_tolstring_dll_cdecl != NULL)
  1243. {
  1244. return g_interfaces[api].lua_tolstring_dll_cdecl(L, index, len);
  1245. }
  1246. else
  1247. {
  1248. return g_interfaces[api].lua_tolstring_dll_stdcall(L, index, len);
  1249. }
  1250. }
  1251. else
  1252. {
  1253. // Lua 4.0 implementation. lua_tolstring doesn't exist, so we just use lua_tostring
  1254. // and compute the length ourself. This means strings with embedded zeros doesn't work
  1255. // in Lua 4.0.
  1256.  
  1257. const char* string = NULL;
  1258.  
  1259. if (g_interfaces[api].lua_tostring_dll_cdecl != NULL)
  1260. {
  1261. string = g_interfaces[api].lua_tostring_dll_cdecl(L, index);
  1262. }
  1263. else
  1264. {
  1265. string = g_interfaces[api].lua_tostring_dll_stdcall(L, index);
  1266. }
  1267.  
  1268. if (len)
  1269. {
  1270. if (string)
  1271. {
  1272. *len = strlen(string);
  1273. }
  1274. else
  1275. {
  1276. *len = 0;
  1277. }
  1278. }
  1279.  
  1280. return string;
  1281.  
  1282. }
  1283. }
  1284.  
  1285. int lua_toboolean_dll(unsigned long api, lua_State* L, int index)
  1286. {
  1287. if (g_interfaces[api].lua_toboolean_dll_cdecl != NULL)
  1288. {
  1289. return g_interfaces[api].lua_toboolean_dll_cdecl(L, index);
  1290. }
  1291. else
  1292. {
  1293. return g_interfaces[api].lua_toboolean_dll_stdcall(L, index);
  1294. }
  1295. }
  1296.  
  1297. int lua_tointeger_dll(unsigned long api, lua_State* L, int index)
  1298. {
  1299. if (g_interfaces[api].lua_tointegerx_dll_cdecl != NULL ||
  1300. g_interfaces[api].lua_tointegerx_dll_stdcall != NULL)
  1301. {
  1302. // Lua 5.2 implementation.
  1303. if (g_interfaces[api].lua_tointegerx_dll_cdecl != NULL)
  1304. {
  1305. return g_interfaces[api].lua_tointegerx_dll_cdecl(L, index, NULL);
  1306. }
  1307. else
  1308. {
  1309. return g_interfaces[api].lua_tointegerx_dll_stdcall(L, index, NULL);
  1310. }
  1311. }
  1312. if (g_interfaces[api].lua_tointeger_dll_cdecl != NULL ||
  1313. g_interfaces[api].lua_tointeger_dll_stdcall != NULL)
  1314. {
  1315. // Lua 5.0 implementation.
  1316. if (g_interfaces[api].lua_tointeger_dll_cdecl != NULL)
  1317. {
  1318. return g_interfaces[api].lua_tointeger_dll_cdecl(L, index);
  1319. }
  1320. else
  1321. {
  1322. return g_interfaces[api].lua_tointeger_dll_stdcall(L, index);
  1323. }
  1324. }
  1325. else
  1326. {
  1327. // On Lua 4.0 fallback to lua_tonumber.
  1328. return static_cast<int>(lua_tonumber_dll(api, L, index));
  1329. }
  1330. }
  1331.  
  1332. lua_CFunction lua_tocfunction_dll(unsigned long api, lua_State* L, int index)
  1333. {
  1334. if (g_interfaces[api].lua_tocfunction_dll_cdecl != NULL)
  1335. {
  1336. return g_interfaces[api].lua_tocfunction_dll_cdecl(L, index);
  1337. }
  1338. else
  1339. {
  1340. return g_interfaces[api].lua_tocfunction_dll_stdcall(L, index);
  1341. }
  1342. }
  1343.  
  1344. lua_Number lua_tonumber_dll(unsigned long api, lua_State* L, int index)
  1345. {
  1346. if (g_interfaces[api].lua_tonumberx_dll_cdecl != NULL ||
  1347. g_interfaces[api].lua_tonumberx_dll_stdcall != NULL)
  1348. {
  1349. // Lua 5.2 implementation.
  1350. if (g_interfaces[api].lua_tonumberx_dll_cdecl != NULL)
  1351. {
  1352. return g_interfaces[api].lua_tonumberx_dll_cdecl(L, index, NULL);
  1353. }
  1354. else
  1355. {
  1356. return g_interfaces[api].lua_tonumberx_dll_stdcall(L, index, NULL);
  1357. }
  1358. }
  1359. // Lua 5.0 and earlier.
  1360. if (g_interfaces[api].lua_tonumber_dll_cdecl != NULL)
  1361. {
  1362. return g_interfaces[api].lua_tonumber_dll_cdecl(L, index);
  1363. }
  1364. else
  1365. {
  1366. return g_interfaces[api].lua_tonumber_dll_stdcall(L, index);
  1367. }
  1368. }
  1369.  
  1370. void* lua_touserdata_dll(unsigned long api, lua_State *L, int index)
  1371. {
  1372. if (g_interfaces[api].lua_touserdata_dll_cdecl != NULL)
  1373. {
  1374. return g_interfaces[api].lua_touserdata_dll_cdecl(L, index);
  1375. }
  1376. else
  1377. {
  1378. return g_interfaces[api].lua_touserdata_dll_stdcall(L, index);
  1379. }
  1380. }
  1381.  
  1382. int lua_gettop_dll(unsigned long api, lua_State* L)
  1383. {
  1384. if (g_interfaces[api].lua_gettop_dll_cdecl != NULL)
  1385. {
  1386. return g_interfaces[api].lua_gettop_dll_cdecl(L);
  1387. }
  1388. else
  1389. {
  1390. return g_interfaces[api].lua_gettop_dll_stdcall(L);
  1391. }
  1392. }
  1393.  
  1394. int lua_loadbuffer_dll(unsigned long api, lua_State* L, const char* buffer, size_t size, const char* chunkname)
  1395. {
  1396.  
  1397. Memory memory;
  1398.  
  1399. memory.buffer = buffer;
  1400. memory.size = size;
  1401.  
  1402. if (g_interfaces[api].lua_load_dll_cdecl != NULL)
  1403. {
  1404. return g_interfaces[api].lua_load_dll_cdecl(L, MemoryReader_cdecl, &memory, chunkname);
  1405. }
  1406. else
  1407. {
  1408. return g_interfaces[api].lua_load_dll_stdcall(L, MemoryReader_stdcall, &memory, chunkname);
  1409. }
  1410.  
  1411. }
  1412.  
  1413. void lua_call_dll(unsigned long api, lua_State* L, int nargs, int nresults)
  1414. {
  1415. if (g_interfaces[api].lua_call_dll_cdecl != NULL)
  1416. {
  1417. return g_interfaces[api].lua_call_dll_cdecl(L, nargs, nresults);
  1418. }
  1419. else
  1420. {
  1421. return g_interfaces[api].lua_call_dll_stdcall(L, nargs, nresults);
  1422. }
  1423. }
  1424.  
  1425. int lua_pcallk_dll(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k)
  1426. {
  1427. if (g_interfaces[api].lua_pcallk_dll_cdecl != NULL)
  1428. {
  1429. return g_interfaces[api].lua_pcallk_dll_cdecl(L, nargs, nresults, errfunc, ctx, k);
  1430. }
  1431. else
  1432. {
  1433. return g_interfaces[api].lua_pcallk_dll_stdcall(L, nargs, nresults, errfunc, ctx, k);
  1434. }
  1435. }
  1436.  
  1437. int lua_pcall_dll(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc)
  1438. {
  1439. // Lua 5.2.
  1440. if (g_interfaces[api].lua_pcallk_dll_cdecl != NULL ||
  1441. g_interfaces[api].lua_pcallk_dll_stdcall != NULL)
  1442. {
  1443. return lua_pcallk_dll(api, L, nargs, nresults, errfunc, 0, NULL);
  1444. }
  1445. // Lua 5.1 and earlier.
  1446. if (g_interfaces[api].lua_pcall_dll_cdecl != NULL)
  1447. {
  1448. return g_interfaces[api].lua_pcall_dll_cdecl(L, nargs, nresults, errfunc);
  1449. }
  1450. else
  1451. {
  1452. return g_interfaces[api].lua_pcall_dll_stdcall(L, nargs, nresults, errfunc);
  1453. }
  1454. }
  1455.  
  1456. void lua_newtable_dll(unsigned long api, lua_State* L)
  1457. {
  1458.  
  1459. if (g_interfaces[api].lua_newtable_dll_cdecl != NULL ||
  1460. g_interfaces[api].lua_newtable_dll_stdcall != NULL)
  1461. {
  1462. // Lua 4.0 implementation.
  1463. if (g_interfaces[api].lua_newtable_dll_cdecl != NULL)
  1464. {
  1465. return g_interfaces[api].lua_newtable_dll_cdecl(L);
  1466. }
  1467. else
  1468. {
  1469. return g_interfaces[api].lua_newtable_dll_stdcall(L);
  1470. }
  1471. }
  1472. else
  1473. {
  1474. // Lua 5.0 version.
  1475. if (g_interfaces[api].lua_createtable_dll_cdecl != NULL)
  1476. {
  1477. g_interfaces[api].lua_createtable_dll_cdecl(L, 0, 0);
  1478. }
  1479. else
  1480. {
  1481. g_interfaces[api].lua_createtable_dll_stdcall(L, 0, 0);
  1482. }
  1483. }
  1484.  
  1485. }
  1486.  
  1487. int lua_next_dll(unsigned long api, lua_State* L, int index)
  1488. {
  1489. if (g_interfaces[api].lua_next_dll_cdecl != NULL)
  1490. {
  1491. return g_interfaces[api].lua_next_dll_cdecl(L, index);
  1492. }
  1493. else
  1494. {
  1495. return g_interfaces[api].lua_next_dll_stdcall(L, index);
  1496. }
  1497. }
  1498.  
  1499. int lua_rawequal_dll(unsigned long api, lua_State *L, int idx1, int idx2)
  1500. {
  1501. if (g_interfaces[api].lua_rawequal_dll_cdecl != NULL)
  1502. {
  1503. return g_interfaces[api].lua_rawequal_dll_cdecl(L, idx1, idx2);
  1504. }
  1505. else
  1506. {
  1507. return g_interfaces[api].lua_rawequal_dll_stdcall(L, idx1, idx2);
  1508. }
  1509. }
  1510.  
  1511. int lua_getmetatable_dll(unsigned long api, lua_State* L, int index)
  1512. {
  1513. if (g_interfaces[api].lua_getmetatable_dll_cdecl != NULL)
  1514. {
  1515. return g_interfaces[api].lua_getmetatable_dll_cdecl(L, index);
  1516. }
  1517. else
  1518. {
  1519. return g_interfaces[api].lua_getmetatable_dll_stdcall(L, index);
  1520. }
  1521. }
  1522.  
  1523. int lua_setmetatable_dll(unsigned long api, lua_State* L, int index)
  1524. {
  1525. if (g_interfaces[api].lua_setmetatable_dll_cdecl != NULL)
  1526. {
  1527. return g_interfaces[api].lua_setmetatable_dll_cdecl(L, index);
  1528. }
  1529. else
  1530. {
  1531. return g_interfaces[api].lua_setmetatable_dll_stdcall(L, index);
  1532. }
  1533. }
  1534.  
  1535. int luaL_ref_dll(unsigned long api, lua_State *L, int t)
  1536. {
  1537. if (g_interfaces[api].luaL_ref_dll_cdecl != NULL)
  1538. {
  1539. return g_interfaces[api].luaL_ref_dll_cdecl(L, t);
  1540. }
  1541. else if (g_interfaces[api].luaL_ref_dll_stdcall != NULL)
  1542. {
  1543. return g_interfaces[api].luaL_ref_dll_stdcall(L, t);
  1544. }
  1545. // We don't require that luaL_ref be present, so provide a suitable
  1546. // implementation if it's not.
  1547. return LUA_NOREF;
  1548. }
  1549.  
  1550. void luaL_unref_dll(unsigned long api, lua_State *L, int t, int ref)
  1551. {
  1552. if (g_interfaces[api].luaL_unref_dll_cdecl != NULL)
  1553. {
  1554. g_interfaces[api].luaL_unref_dll_cdecl(L, t, ref);
  1555. }
  1556. else if (g_interfaces[api].luaL_ref_dll_stdcall != NULL)
  1557. {
  1558. g_interfaces[api].luaL_unref_dll_stdcall(L, t, ref);
  1559. }
  1560. }
  1561.  
  1562. int luaL_newmetatable_dll(unsigned long api, lua_State *L, const char *tname)
  1563. {
  1564. if (g_interfaces[api].luaL_newmetatable_dll_cdecl != NULL)
  1565. {
  1566. return g_interfaces[api].luaL_newmetatable_dll_cdecl(L, tname);
  1567. }
  1568. else
  1569. {
  1570. return g_interfaces[api].luaL_newmetatable_dll_stdcall(L, tname);
  1571. }
  1572. }
  1573.  
  1574. int luaL_loadbuffer_dll(unsigned long api, lua_State *L, const char *buff, size_t sz, const char *name)
  1575. {
  1576. if (g_interfaces[api].luaL_loadbuffer_dll_cdecl != NULL)
  1577. {
  1578. return g_interfaces[api].luaL_loadbuffer_dll_cdecl(L, buff, sz, name);
  1579. }
  1580. else
  1581. {
  1582. return g_interfaces[api].luaL_loadbuffer_dll_stdcall(L, buff, sz, name);
  1583. }
  1584. }
  1585.  
  1586. int luaL_loadfile_dll(unsigned long api, lua_State* L, const char* fileName)
  1587. {
  1588. if (g_interfaces[api].luaL_loadfile_dll_cdecl != NULL)
  1589. {
  1590. return g_interfaces[api].luaL_loadfile_dll_cdecl(L, fileName);
  1591. }
  1592. else
  1593. {
  1594. return g_interfaces[api].luaL_loadfile_dll_stdcall(L, fileName);
  1595. }
  1596. }
  1597.  
  1598. lua_State* luaL_newstate_dll(unsigned long api)
  1599. {
  1600. if (g_interfaces[api].luaL_newstate_dll_cdecl != NULL)
  1601. {
  1602. return g_interfaces[api].luaL_newstate_dll_cdecl();
  1603. }
  1604. else
  1605. {
  1606. return g_interfaces[api].luaL_newstate_dll_stdcall();
  1607. }
  1608. }
  1609.  
  1610. const lua_WChar* lua_towstring_dll(unsigned long api, lua_State* L, int index)
  1611. {
  1612. if (g_interfaces[api].lua_towstring_dll_cdecl != NULL ||
  1613. g_interfaces[api].lua_towstring_dll_stdcall != NULL)
  1614. {
  1615. if (g_interfaces[api].lua_towstring_dll_cdecl != NULL)
  1616. {
  1617. return g_interfaces[api].lua_towstring_dll_cdecl(L, index);
  1618. }
  1619. else
  1620. {
  1621. return g_interfaces[api].lua_towstring_dll_stdcall(L, index);
  1622. }
  1623. }
  1624. else
  1625. {
  1626. // The application is not using LuaPlus, so just return NULL.
  1627. return NULL;
  1628. }
  1629. }
  1630.  
  1631. int lua_iswstring_dll(unsigned long api, lua_State* L, int index)
  1632. {
  1633. if (g_interfaces[api].lua_iswstring_dll_cdecl != NULL ||
  1634. g_interfaces[api].lua_iswstring_dll_stdcall != NULL)
  1635. {
  1636. if (g_interfaces[api].lua_iswstring_dll_cdecl != NULL)
  1637. {
  1638. return g_interfaces[api].lua_iswstring_dll_cdecl(L, index);
  1639. }
  1640. else
  1641. {
  1642. return g_interfaces[api].lua_iswstring_dll_stdcall(L, index);
  1643. }
  1644. }
  1645. else
  1646. {
  1647. // The application is not using LuaPlus, so just return 0.
  1648. return 0;
  1649. }
  1650. }
  1651.  
  1652. const char* lua_getupvalue_dll(unsigned long api, lua_State *L, int funcindex, int n)
  1653. {
  1654. if (g_interfaces[api].lua_getupvalue_dll_cdecl != NULL)
  1655. {
  1656. return g_interfaces[api].lua_getupvalue_dll_cdecl(L, funcindex, n);
  1657. }
  1658. else
  1659. {
  1660. return g_interfaces[api].lua_getupvalue_dll_stdcall(L, funcindex, n);
  1661. }
  1662. }
  1663.  
  1664. const char* lua_setupvalue_dll(unsigned long api, lua_State *L, int funcindex, int n)
  1665. {
  1666. if (g_interfaces[api].lua_setupvalue_dll_cdecl != NULL)
  1667. {
  1668. return g_interfaces[api].lua_setupvalue_dll_cdecl(L, funcindex, n);
  1669. }
  1670. else
  1671. {
  1672. return g_interfaces[api].lua_setupvalue_dll_stdcall(L, funcindex, n);
  1673. }
  1674. }
  1675.  
  1676. void lua_getfenv_dll(unsigned long api, lua_State *L, int index)
  1677. {
  1678. if (g_interfaces[api].lua_getfenv_dll_cdecl != NULL)
  1679. {
  1680. g_interfaces[api].lua_getfenv_dll_cdecl(L, index);
  1681. }
  1682. else
  1683. {
  1684. g_interfaces[api].lua_getfenv_dll_stdcall(L, index);
  1685. }
  1686. }
  1687.  
  1688. int lua_setfenv_dll(unsigned long api, lua_State *L, int index)
  1689. {
  1690. if (g_interfaces[api].lua_setfenv_dll_cdecl != NULL)
  1691. {
  1692. return g_interfaces[api].lua_setfenv_dll_cdecl(L, index);
  1693. }
  1694. else
  1695. {
  1696. return g_interfaces[api].lua_setfenv_dll_stdcall(L, index);
  1697. }
  1698. }
  1699.  
  1700. int lua_cpcall_dll(unsigned long api, lua_State *L, lua_CFunction func, void *ud)
  1701. {
  1702. if (g_interfaces[api].lua_cpcall_dll_cdecl != NULL)
  1703. {
  1704. return g_interfaces[api].lua_cpcall_dll_cdecl(L, func, ud);
  1705. }
  1706. else
  1707. {
  1708. return g_interfaces[api].lua_cpcall_dll_stdcall(L, func, ud);
  1709. }
  1710. }
  1711.  
  1712. HMODULE WINAPI LoadLibraryExW_intercept(LPCWSTR fileName, HANDLE hFile, DWORD dwFlags)
  1713. {
  1714.  
  1715. // We have to call the loader lock (if it is available) so that we don't get deadlocks
  1716. // in the case where Dll initialization acquires the loader lock and calls LoadLibrary
  1717. // while another thread is inside PostLoadLibrary.
  1718.  
  1719. ULONG cookie;
  1720.  
  1721. if (LdrLockLoaderLock_dll != NULL &&
  1722. LdrUnlockLoaderLock_dll != NULL)
  1723. {
  1724. LdrLockLoaderLock_dll(0, 0, &cookie);
  1725. }
  1726.  
  1727. HMODULE hModule = LoadLibraryExW_dll(fileName, hFile, dwFlags);
  1728.  
  1729. if (hModule != NULL)
  1730. {
  1731. PostLoadLibrary(hModule);
  1732. }
  1733.  
  1734. if (LdrLockLoaderLock_dll != NULL &&
  1735. LdrUnlockLoaderLock_dll != NULL)
  1736. {
  1737. LdrUnlockLoaderLock_dll(0, cookie);
  1738. }
  1739.  
  1740. return hModule;
  1741.  
  1742. }
  1743.  
  1744. void FinishLoadingLua(unsigned long api, bool stdcall)
  1745. {
  1746.  
  1747. #define SET_STDCALL(function) \
  1748. if ( g_interfaces[api].function##_dll_cdecl != NULL) { \
  1749. g_interfaces[api].function##_dll_stdcall = reinterpret_cast<function##_stdcall_t>(g_interfaces[api].function##_dll_cdecl); \
  1750. g_interfaces[api].function##_dll_cdecl = NULL; \
  1751. }
  1752.  
  1753. if (g_interfaces[api].finishedLoading)
  1754. {
  1755. return;
  1756. }
  1757.  
  1758. g_interfaces[api].stdcall = stdcall;
  1759.  
  1760. if (stdcall)
  1761. {
  1762. SET_STDCALL(lua_newstate);
  1763. SET_STDCALL(lua_open);
  1764. SET_STDCALL(lua_open_500);
  1765. SET_STDCALL(lua_newstate);
  1766. SET_STDCALL(lua_newthread);
  1767. SET_STDCALL(lua_close);
  1768. SET_STDCALL(lua_error);
  1769. SET_STDCALL(lua_sethook);
  1770. SET_STDCALL(lua_getinfo);
  1771. SET_STDCALL(lua_remove);
  1772. SET_STDCALL(lua_settable);
  1773. SET_STDCALL(lua_gettable);
  1774. SET_STDCALL(lua_rawget);
  1775. SET_STDCALL(lua_rawgeti);
  1776. SET_STDCALL(lua_rawset);
  1777. SET_STDCALL(lua_pushstring);
  1778. SET_STDCALL(lua_pushlstring);
  1779. SET_STDCALL(lua_type);
  1780. SET_STDCALL(lua_typename);
  1781. SET_STDCALL(lua_settop);
  1782. SET_STDCALL(lua_gettop);
  1783. SET_STDCALL(lua_getlocal);
  1784. SET_STDCALL(lua_setlocal);
  1785. SET_STDCALL(lua_getstack);
  1786. SET_STDCALL(lua_insert);
  1787. SET_STDCALL(lua_pushnil);
  1788. SET_STDCALL(lua_pushvalue);
  1789. SET_STDCALL(lua_pushinteger);
  1790. SET_STDCALL(lua_pushnumber);
  1791. SET_STDCALL(lua_pushcclosure);
  1792. SET_STDCALL(lua_pushlightuserdata);
  1793. SET_STDCALL(lua_tostring);
  1794. SET_STDCALL(lua_tolstring);
  1795. SET_STDCALL(lua_toboolean);
  1796. SET_STDCALL(lua_tointeger);
  1797. SET_STDCALL(lua_tointegerx);
  1798. SET_STDCALL(lua_tocfunction);
  1799. SET_STDCALL(lua_tonumber);
  1800. SET_STDCALL(lua_tonumberx);
  1801. SET_STDCALL(lua_touserdata);
  1802. SET_STDCALL(lua_call);
  1803. SET_STDCALL(lua_callk);
  1804. SET_STDCALL(lua_pcall);
  1805. SET_STDCALL(lua_pcallk);
  1806. SET_STDCALL(lua_newtable);
  1807. SET_STDCALL(lua_createtable);
  1808. SET_STDCALL(lua_load);
  1809. SET_STDCALL(lua_next);
  1810. SET_STDCALL(lua_rawequal);
  1811. SET_STDCALL(lua_getmetatable);
  1812. SET_STDCALL(lua_setmetatable);
  1813. SET_STDCALL(luaL_ref);
  1814. SET_STDCALL(luaL_unref);
  1815. SET_STDCALL(luaL_newmetatable);
  1816. SET_STDCALL(luaL_loadbuffer);
  1817. SET_STDCALL(luaL_loadfile);
  1818. SET_STDCALL(lua_getupvalue);
  1819. SET_STDCALL(lua_setupvalue);
  1820. SET_STDCALL(lua_getfenv);
  1821. SET_STDCALL(lua_setfenv);
  1822. SET_STDCALL(lua_cpcall);
  1823. SET_STDCALL(lua_pushthread);
  1824. SET_STDCALL(lua_newuserdata);
  1825. SET_STDCALL(lua_pushthread);
  1826. SET_STDCALL(lua_checkstack);
  1827. }
  1828.  
  1829. g_interfaces[api].finishedLoading = true;
  1830.  
  1831. DebugBackend::Get().CreateApi(api);
  1832.  
  1833. }
  1834.  
  1835. #pragma auto_inline(off)
  1836. void lua_call_worker(unsigned long api, lua_State* L, int nargs, int nresults, bool& stdcall)
  1837. {
  1838.  
  1839. if (!g_interfaces[api].finishedLoading)
  1840. {
  1841.  
  1842. int result;
  1843. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_call_dll_cdecl, (void*)L, (void*)nargs, (void*)nresults, (void**)&result);
  1844.  
  1845. FinishLoadingLua(api, stdcall);
  1846. DebugBackend::Get().AttachState(api, L);
  1847.  
  1848. }
  1849. else
  1850. {
  1851.  
  1852. DebugBackend::Get().AttachState(api, L);
  1853.  
  1854. if (g_interfaces[api].lua_call_dll_cdecl != NULL)
  1855. {
  1856. stdcall = false;
  1857. }
  1858. else if (g_interfaces[api].lua_call_dll_stdcall != NULL)
  1859. {
  1860. stdcall = true;
  1861. }
  1862.  
  1863. if (lua_gettop_dll(api, L) < nargs + 1)
  1864. {
  1865. DebugBackend::Get().Message("Warning 1005: lua_call called with too few arguments on the stack", MessageType_Warning);
  1866. }
  1867.  
  1868. if (DebugBackend::Get().Call(api, L, nargs, nresults, 0))
  1869. {
  1870. lua_error_dll(api, L);
  1871. }
  1872.  
  1873. }
  1874.  
  1875. }
  1876. #pragma auto_inline()
  1877.  
  1878. // This function cannot be called like a normal function. It changes its
  1879. // calling convention at run-time and removes and extra argument from the stack.
  1880. __declspec(naked) void lua_call_intercept(unsigned long api, lua_State* L, int nargs, int nresults)
  1881. {
  1882.  
  1883. bool stdcall;
  1884.  
  1885. INTERCEPT_PROLOG()
  1886.  
  1887. // We push the actual functionality of this function into a separate, "normal"
  1888. // function so avoid interferring with the inline assembly and other strange
  1889. // aspects of this function.
  1890. lua_call_worker(api, L, nargs, nresults, stdcall);
  1891.  
  1892. INTERCEPT_EPILOG_NO_RETURN(12)
  1893.  
  1894. }
  1895.  
  1896. #pragma auto_inline(off)
  1897. void lua_callk_worker(unsigned long api, lua_State* L, int nargs, int nresults, int ctk, lua_CFunction k, bool& stdcall)
  1898. {
  1899.  
  1900. if (!g_interfaces[api].finishedLoading)
  1901. {
  1902.  
  1903. int result;
  1904. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_callk_dll_cdecl, (void*)L, (void*)nargs, (void*)nresults, (void*)ctk, (void*)k, (void**)&result);
  1905.  
  1906. FinishLoadingLua(api, stdcall);
  1907. DebugBackend::Get().AttachState(api, L);
  1908.  
  1909. }
  1910. else
  1911. {
  1912.  
  1913. DebugBackend::Get().AttachState(api, L);
  1914.  
  1915. if (g_interfaces[api].lua_callk_dll_cdecl != NULL)
  1916. {
  1917. stdcall = false;
  1918. }
  1919. else if (g_interfaces[api].lua_callk_dll_stdcall != NULL)
  1920. {
  1921. stdcall = true;
  1922. }
  1923.  
  1924. if (lua_gettop_dll(api, L) < nargs + 1)
  1925. {
  1926. DebugBackend::Get().Message("Warning 1005: lua_call called with too few arguments on the stack", MessageType_Warning);
  1927. }
  1928.  
  1929. if (DebugBackend::Get().Call(api, L, nargs, nresults, 0))
  1930. {
  1931. lua_error_dll(api, L);
  1932. }
  1933.  
  1934. }
  1935.  
  1936. }
  1937. #pragma auto_inline()
  1938.  
  1939. // This function cannot be called like a normal function. It changes its
  1940. // calling convention at run-time and removes and extra argument from the stack.
  1941. __declspec(naked) void lua_callk_intercept(unsigned long api, lua_State* L, int nargs, int nresults, int ctx, lua_CFunction k)
  1942. {
  1943.  
  1944. bool stdcall;
  1945.  
  1946. INTERCEPT_PROLOG()
  1947.  
  1948. // We push the actual functionality of this function into a separate, "normal"
  1949. // function so avoid interferring with the inline assembly and other strange
  1950. // aspects of this function.
  1951. lua_callk_worker(api, L, nargs, nresults, ctx, k, stdcall);
  1952.  
  1953. INTERCEPT_EPILOG_NO_RETURN(20)
  1954.  
  1955. }
  1956.  
  1957.  
  1958. #pragma auto_inline(off)
  1959. int lua_pcall_worker(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc, bool& stdcall)
  1960. {
  1961.  
  1962. int result;
  1963.  
  1964. if (!g_interfaces[api].finishedLoading)
  1965. {
  1966.  
  1967. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_pcall_dll_cdecl, (void*)L, (void*)nargs, (void*)nresults, (void*)errfunc, (void**)&result);
  1968.  
  1969. FinishLoadingLua(api, stdcall);
  1970. DebugBackend::Get().AttachState(api, L);
  1971.  
  1972. }
  1973. else
  1974. {
  1975.  
  1976. DebugBackend::Get().AttachState(api, L);
  1977.  
  1978. if (g_interfaces[api].lua_pcall_dll_cdecl != NULL)
  1979. {
  1980. stdcall = false;
  1981. }
  1982. else if (g_interfaces[api].lua_pcall_dll_stdcall != NULL)
  1983. {
  1984. stdcall = true;
  1985. }
  1986.  
  1987. if (lua_gettop_dll(api, L) < nargs + 1)
  1988. {
  1989. DebugBackend::Get().Message("Warning 1005: lua_pcall called with too few arguments on the stack", MessageType_Warning);
  1990. }
  1991.  
  1992. if (GetAreInterceptsEnabled())
  1993. {
  1994. result = DebugBackend::Get().Call(api, L, nargs, nresults, errfunc);
  1995. }
  1996. else
  1997. {
  1998. result = lua_pcall_dll(api, L, nargs, nresults, errfunc);
  1999. }
  2000.  
  2001. }
  2002.  
  2003. return result;
  2004.  
  2005. }
  2006. #pragma auto_inline()
  2007.  
  2008. // This function cannot be called like a normal function. It changes its
  2009. // calling convention at run-time and removes and extra argument from the stack.
  2010. __declspec(naked) int lua_pcall_intercept(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc)
  2011. {
  2012.  
  2013. int result;
  2014. bool stdcall;
  2015.  
  2016. INTERCEPT_PROLOG()
  2017.  
  2018. // We push the actual functionality of this function into a separate, "normal"
  2019. // function so avoid interferring with the inline assembly and other strange
  2020. // aspects of this function.
  2021. result = lua_pcall_worker(api, L, nargs, nresults, errfunc, stdcall);
  2022.  
  2023. INTERCEPT_EPILOG(16)
  2024.  
  2025. }
  2026.  
  2027. #pragma auto_inline(off)
  2028. int lua_pcallk_worker(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k, bool& stdcall)
  2029. {
  2030.  
  2031. int result;
  2032.  
  2033. if (!g_interfaces[api].finishedLoading)
  2034. {
  2035.  
  2036. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_pcall_dll_cdecl, (void*)L, (void*)nargs,
  2037. (void*)nresults, (void*)errfunc, (void*)ctx, (void*)k, (void**)&result);
  2038.  
  2039. FinishLoadingLua(api, stdcall);
  2040. DebugBackend::Get().AttachState(api, L);
  2041.  
  2042. }
  2043. else
  2044. {
  2045.  
  2046. DebugBackend::Get().AttachState(api, L);
  2047.  
  2048. if (g_interfaces[api].lua_pcallk_dll_cdecl != NULL)
  2049. {
  2050. stdcall = false;
  2051. }
  2052. else if (g_interfaces[api].lua_pcallk_dll_stdcall != NULL)
  2053. {
  2054. stdcall = true;
  2055. }
  2056.  
  2057. if (lua_gettop_dll(api, L) < nargs + 1)
  2058. {
  2059. DebugBackend::Get().Message("Warning 1005: lua_pcallk called with too few arguments on the stack", MessageType_Warning);
  2060. }
  2061.  
  2062. if (GetAreInterceptsEnabled())
  2063. {
  2064. result = DebugBackend::Get().Call(api, L, nargs, nresults, errfunc);
  2065. }
  2066. else
  2067. {
  2068. result = lua_pcallk_dll(api, L, nargs, nresults, errfunc, ctx, k);
  2069. }
  2070.  
  2071. }
  2072.  
  2073. return result;
  2074.  
  2075. }
  2076. #pragma auto_inline()
  2077.  
  2078. // This function cannot be called like a normal function. It changes its
  2079. // calling convention at run-time and removes and extra argument from the stack.
  2080. __declspec(naked) int lua_pcallk_intercept(unsigned long api, lua_State* L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k)
  2081. {
  2082.  
  2083. int result;
  2084. bool stdcall;
  2085.  
  2086. INTERCEPT_PROLOG()
  2087.  
  2088. // We push the actual functionality of this function into a separate, "normal"
  2089. // function so avoid interferring with the inline assembly and other strange
  2090. // aspects of this function.
  2091. result = lua_pcallk_worker(api, L, nargs, nresults, errfunc, ctx, k, stdcall);
  2092.  
  2093. INTERCEPT_EPILOG(24)
  2094.  
  2095. }
  2096.  
  2097. #pragma auto_inline(off)
  2098. lua_State* lua_newstate_worker(unsigned long api, lua_Alloc f, void* ud, bool& stdcall)
  2099. {
  2100.  
  2101. lua_State* result = NULL;
  2102.  
  2103. if (!g_interfaces[api].finishedLoading)
  2104. {
  2105. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_newstate_dll_cdecl, (void*)f, ud, (void**)&result);
  2106. FinishLoadingLua(api, stdcall);
  2107. }
  2108. else if (g_interfaces[api].lua_newstate_dll_cdecl != NULL)
  2109. {
  2110. result = g_interfaces[api].lua_newstate_dll_cdecl(f, ud);
  2111. stdcall = false;
  2112. }
  2113. else if (g_interfaces[api].lua_newstate_dll_stdcall != NULL)
  2114. {
  2115. result = g_interfaces[api].lua_newstate_dll_stdcall(f, ud);
  2116. stdcall = true;
  2117. }
  2118.  
  2119. if (result != NULL)
  2120. {
  2121. DebugBackend::Get().AttachState(api, result);
  2122. }
  2123.  
  2124. return result;
  2125.  
  2126. }
  2127. #pragma auto_inline()
  2128.  
  2129. // This function cannot be called like a normal function. It changes its
  2130. // calling convention at run-time and removes and extra argument from the stack.
  2131. __declspec(naked) lua_State* lua_newstate_intercept(unsigned long api, lua_Alloc f, void* ud)
  2132. {
  2133.  
  2134. lua_State* result;
  2135. bool stdcall;
  2136.  
  2137. INTERCEPT_PROLOG()
  2138.  
  2139. // We push the actual functionality of this function into a separate, "normal"
  2140. // function so avoid interferring with the inline assembly and other strange
  2141. // aspects of this function.
  2142. result = lua_newstate_worker(api, f, ud, stdcall);
  2143.  
  2144. INTERCEPT_EPILOG(8)
  2145.  
  2146. }
  2147.  
  2148. #pragma auto_inline(off)
  2149. lua_State* lua_newthread_worker(unsigned long api, lua_State* L, bool& stdcall)
  2150. {
  2151.  
  2152. lua_State* result = NULL;
  2153.  
  2154. if (!g_interfaces[api].finishedLoading)
  2155. {
  2156. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_newthread_dll_cdecl, L, (void**)&result);
  2157. FinishLoadingLua(api, stdcall);
  2158. }
  2159. else if (g_interfaces[api].lua_newthread_dll_cdecl != NULL)
  2160. {
  2161. result = g_interfaces[api].lua_newthread_dll_cdecl(L);
  2162. stdcall = false;
  2163. }
  2164. else if (g_interfaces[api].lua_newthread_dll_stdcall != NULL)
  2165. {
  2166. result = g_interfaces[api].lua_newthread_dll_stdcall(L);
  2167. stdcall = true;
  2168. }
  2169.  
  2170. if (result != NULL)
  2171. {
  2172. DebugBackend::Get().AttachState(api, result);
  2173. }
  2174.  
  2175. return result;
  2176.  
  2177. }
  2178. #pragma auto_inline()
  2179.  
  2180. // This function cannot be called like a normal function. It changes its
  2181. // calling convention at run-time and removes and extra argument from the stack.
  2182. __declspec(naked) lua_State* lua_newthread_intercept(unsigned long api, lua_State* L)
  2183. {
  2184.  
  2185. lua_State* result;
  2186. bool stdcall;
  2187.  
  2188. INTERCEPT_PROLOG()
  2189.  
  2190. // We push the actual functionality of this function into a separate, "normal"
  2191. // function so avoid interferring with the inline assembly and other strange
  2192. // aspects of this function.
  2193. result = lua_newthread_worker(api, L, stdcall);
  2194.  
  2195. INTERCEPT_EPILOG(4)
  2196.  
  2197. }
  2198.  
  2199. #pragma auto_inline(off)
  2200. lua_State* lua_open_worker(unsigned long api, int stacksize, bool& stdcall)
  2201. {
  2202.  
  2203. lua_State* result = NULL;
  2204.  
  2205. if (!g_interfaces[api].finishedLoading)
  2206. {
  2207. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_open_dll_cdecl, (void*)stacksize, (void**)&result);
  2208. FinishLoadingLua(api, stdcall);
  2209. }
  2210. else if (g_interfaces[api].lua_open_dll_cdecl != NULL)
  2211. {
  2212. result = g_interfaces[api].lua_open_dll_cdecl(stacksize);
  2213. stdcall = false;
  2214. }
  2215. else if (g_interfaces[api].lua_open_dll_stdcall != NULL)
  2216. {
  2217. result = g_interfaces[api].lua_open_dll_stdcall(stacksize);
  2218. stdcall = true;
  2219. }
  2220.  
  2221. if (result != NULL)
  2222. {
  2223. DebugBackend::Get().AttachState(api, result);
  2224. }
  2225.  
  2226. return result;
  2227.  
  2228. }
  2229. #pragma auto_inline()
  2230.  
  2231. #pragma auto_inline(off)
  2232. lua_State* lua_open_500_worker(unsigned long api, bool& stdcall)
  2233. {
  2234.  
  2235. lua_State* result = NULL;
  2236.  
  2237. if (!g_interfaces[api].finishedLoading)
  2238. {
  2239.  
  2240. // We can't test stdcall with the Lua 5.0 lua_open function since it doesn't
  2241. // take any arguments. To do the test, we create a dummy state and destroy it
  2242. // using the lua_close function to do the test.
  2243.  
  2244. lua_State* L = g_interfaces[api].lua_open_500_dll_cdecl();
  2245. stdcall = GetIsStdCallConvention( g_interfaces[api].lua_close_dll_cdecl, (void*)L, (void**)&result);
  2246. FinishLoadingLua(api, stdcall);
  2247.  
  2248. }
  2249.  
  2250. if (g_interfaces[api].lua_open_500_dll_cdecl != NULL)
  2251. {
  2252. result = g_interfaces[api].lua_open_500_dll_cdecl();
  2253. stdcall = false;
  2254. }
  2255. else if (g_interfaces[api].lua_open_500_dll_stdcall != NULL)
  2256. {
  2257. result = g_interfaces[api].lua_open_500_dll_stdcall();
  2258. stdcall = true;
  2259. }
  2260.  
  2261. if (result != NULL)
  2262. {
  2263. DebugBackend::Get().AttachState(api, result);
  2264. }
  2265.  
  2266. return result;
  2267.  
  2268. }
  2269. #pragma auto_inline()
  2270.  
  2271. // This function cannot be called like a normal function. It changes its
  2272. // calling convention at run-time and removes and extra argument from the stack.
  2273. __declspec(naked) lua_State* lua_open_intercept(unsigned long api, int stacksize)
  2274. {
  2275.  
  2276. lua_State* result;
  2277. bool stdcall;
  2278.  
  2279. INTERCEPT_PROLOG()
  2280.  
  2281. // We push the actual functionality of this function into a separate, "normal"
  2282. // function so avoid interferring with the inline assembly and other strange
  2283. // aspects of this function.
  2284. result = lua_open_worker(api, stacksize, stdcall);
  2285.  
  2286. INTERCEPT_EPILOG(4)
  2287.  
  2288. }
  2289.  
  2290. // This function cannot be called like a normal function. It changes its
  2291. // calling convention at run-time and removes and extra argument from the stack.
  2292. __declspec(naked) lua_State* lua_open_500_intercept(unsigned long api)
  2293. {
  2294.  
  2295. lua_State* result;
  2296. bool stdcall;
  2297.  
  2298. INTERCEPT_PROLOG()
  2299.  
  2300. // We push the actual functionality of this function into a separate, "normal"
  2301. // function so avoid interferring with the inline assembly and other strange
  2302. // aspects of this function.
  2303. result = lua_open_500_worker(api, stdcall);
  2304.  
  2305. INTERCEPT_EPILOG(0)
  2306.  
  2307. }
  2308.  
  2309. #pragma auto_inline(off)
  2310. int lua_load_worker(unsigned long api, lua_State* L, lua_Reader reader, void* data, const char* name, bool& stdcall)
  2311. {
  2312.  
  2313. // If we haven't finished loading yet this will be wrong, but we'll fix it up
  2314. // when we access the reader function.
  2315. stdcall = (g_interfaces[api].lua_load_dll_stdcall != NULL);
  2316.  
  2317. // Read all of the data out of the reader and into a big buffer.
  2318.  
  2319. std::vector<char> buffer;
  2320.  
  2321. const char* chunk;
  2322. size_t chunkSize;
  2323.  
  2324. do
  2325. {
  2326.  
  2327. if (!g_interfaces[api].finishedLoading)
  2328. {
  2329. // In this case we must have attached the debugger so we're intercepting a lua_load
  2330. // function before we've initialized.
  2331. stdcall = GetIsStdCallConvention(reader, L, data, &chunkSize, (void**)&chunk);
  2332. FinishLoadingLua(api, stdcall);
  2333. }
  2334. else if (stdcall)
  2335. {
  2336. // We assume that since the lua_load function is stdcall the reader function is as well.
  2337. chunk = reinterpret_cast<lua_Reader_stdcall>(reader)(L, data, &chunkSize);
  2338. }
  2339. else
  2340. {
  2341. // We assume that since the lua_load function is cdecl the reader function is as well.
  2342. chunk = reader(L, data, &chunkSize);
  2343. }
  2344.  
  2345. // We allow the reader to return 0 for the chunk size since Lua supports
  2346. // that, although according to the manual it should return NULL to signal
  2347. // the end of the data.
  2348.  
  2349. if (chunk != NULL && chunkSize > 0)
  2350. {
  2351. buffer.insert(buffer.end(), chunk, chunk + chunkSize);
  2352. }
  2353.  
  2354. }
  2355. while (chunk != NULL && chunkSize > 0);
  2356.  
  2357. const char* source = NULL;
  2358.  
  2359. if (!buffer.empty())
  2360. {
  2361. source = &buffer[0];
  2362. }
  2363.  
  2364. // Make sure the debugger knows about this state. This is necessary since we might have
  2365. // attached the debugger after the state was created.
  2366. DebugBackend::Get().AttachState(api, L);
  2367.  
  2368. // Disables JIT compilation if LuaJIT is being used. Otherwise we won't get hooks for
  2369. // this chunk.
  2370. if (DebugBackend::Get().EnableJit(api, L, false))
  2371. {
  2372. if (!g_warnedAboutJit)
  2373. {
  2374. DebugBackend::Get().Message("Warning 1007: Just-in-time compilation of Lua code disabled to allow debugging", MessageType_Warning);
  2375. g_warnedAboutJit = true;
  2376. }
  2377. }
  2378.  
  2379. int result = lua_loadbuffer_dll(api, L, source, buffer.size(), name);
  2380.  
  2381. if (!buffer.empty())
  2382. {
  2383. result = DebugBackend::Get().PostLoadScript(api, result, L, source, buffer.size(), name);
  2384. }
  2385.  
  2386. return result;
  2387.  
  2388. }
  2389. #pragma auto_inline()
  2390.  
  2391. // This function cannot be called like a normal function. It changes its
  2392. // calling convention at run-time and removes and extra argument from the stack.
  2393. __declspec(naked) int lua_load_intercept(unsigned long api, lua_State* L, lua_Reader reader, void* data, const char* name)
  2394. {
  2395.  
  2396. bool stdcall;
  2397. int result;
  2398.  
  2399. INTERCEPT_PROLOG()
  2400.  
  2401. // We push the actual functionality of this function into a separate, "normal"
  2402. // function so avoid interferring with the inline assembly and other strange
  2403. // aspects of this function.
  2404. result = lua_load_worker(api, L, reader, data, name, stdcall);
  2405.  
  2406. INTERCEPT_EPILOG(16)
  2407.  
  2408. }
  2409.  
  2410. #pragma auto_inline(off)
  2411. void lua_close_worker(unsigned long api, lua_State* L, bool& stdcall)
  2412. {
  2413.  
  2414. if (!g_interfaces[api].finishedLoading)
  2415. {
  2416. stdcall = GetIsStdCallConvention(g_interfaces[api].lua_close_dll_cdecl, L, NULL);
  2417. FinishLoadingLua(api, stdcall);
  2418. }
  2419. else if (g_interfaces[api].lua_close_dll_cdecl != NULL)
  2420. {
  2421. g_interfaces[api].lua_close_dll_cdecl(L);
  2422. stdcall = false;
  2423. }
  2424. else if (g_interfaces[api].lua_close_dll_stdcall != NULL)
  2425. {
  2426. g_interfaces[api].lua_close_dll_stdcall(L);
  2427. stdcall = true;
  2428. }
  2429.  
  2430. DebugBackend::Get().DetachState(api, L);
  2431.  
  2432. }
  2433. #pragma auto_inline()
  2434.  
  2435. // This function cannot be called like a normal function. It changes its
  2436. // calling convention at run-time and removes and extra argument from the stack.
  2437. __declspec(naked) void lua_close_intercept(unsigned long api, lua_State* L)
  2438. {
  2439.  
  2440. bool stdcall;
  2441.  
  2442. INTERCEPT_PROLOG()
  2443.  
  2444. // We push the actual functionality of this function into a separate, "normal"
  2445. // function so avoid interferring with the inline assembly and other strange
  2446. // aspects of this function.
  2447. lua_close_worker(api, L, stdcall);
  2448.  
  2449. INTERCEPT_EPILOG_NO_RETURN(4)
  2450.  
  2451. }
  2452.  
  2453. #pragma auto_inline(off)
  2454. int luaL_newmetatable_worker(unsigned long api, lua_State *L, const char* tname, bool& stdcall)
  2455. {
  2456.  
  2457. int result;
  2458.  
  2459. if (!g_interfaces[api].finishedLoading)
  2460. {
  2461. stdcall = GetIsStdCallConvention(g_interfaces[api].luaL_newmetatable_dll_cdecl, L, (void*)tname, (void**)&result);
  2462. FinishLoadingLua(api, stdcall);
  2463. }
  2464. else if (g_interfaces[api].luaL_newmetatable_dll_cdecl != NULL)
  2465. {
  2466. result = g_interfaces[api].luaL_newmetatable_dll_cdecl(L, tname);
  2467. stdcall = false;
  2468. }
  2469. else if (g_interfaces[api].luaL_newmetatable_dll_stdcall != NULL)
  2470. {
  2471. result = g_interfaces[api].luaL_newmetatable_dll_stdcall(L, tname);
  2472. stdcall = true;
  2473. }
  2474.  
  2475. if (result != 0)
  2476. {
  2477. // Only register if we haven't seen this name before.
  2478. DebugBackend::Get().RegisterClassName(api, L, tname, lua_gettop_dll(api, L));
  2479. }
  2480.  
  2481. return result;
  2482.  
  2483. }
  2484. #pragma auto_inline()
  2485.  
  2486. // This function cannot be called like a normal function. It changes its
  2487. // calling convention at run-time and removes and extra argument from the stack.
  2488. __declspec(naked) int luaL_newmetatable_intercept(unsigned long api, lua_State* L, const char* tname)
  2489. {
  2490.  
  2491. int result;
  2492. bool stdcall;
  2493.  
  2494. INTERCEPT_PROLOG()
  2495.  
  2496. // We push the actual functionality of this function into a separate, "normal"
  2497. // function so avoid interferring with the inline assembly and other strange
  2498. // aspects of this function.
  2499. result = luaL_newmetatable_worker(api, L, tname, stdcall);
  2500.  
  2501. INTERCEPT_EPILOG(8)
  2502.  
  2503. }
  2504.  
  2505. #pragma auto_inline(off)
  2506. int lua_sethook_worker(unsigned long api, lua_State *L, lua_Hook f, int mask, int count, bool& stdcall)
  2507. {
  2508.  
  2509. // Currently we're using the hook and can't let anyone else use it.
  2510. // What we should do is implement the lua hook on top of our existing hook.
  2511.  
  2512. int result = 0;
  2513.  
  2514. if (!g_interfaces[api].finishedLoading)
  2515. {
  2516. stdcall = GetIsStdCallConvention(g_interfaces[api].lua_sethook_dll_cdecl, L, f, (void*)mask, (void*)count, (void**)&result);
  2517. FinishLoadingLua(api, stdcall);
  2518. DebugBackend::Get().AttachState(api, L);
  2519. }
  2520. else
  2521. {
  2522. if (g_interfaces[api].luaL_newmetatable_dll_cdecl != NULL)
  2523. {
  2524. stdcall = false;
  2525. }
  2526. else if (g_interfaces[api].luaL_newmetatable_dll_stdcall != NULL)
  2527. {
  2528. stdcall = true;
  2529. }
  2530. // Note, the lua_hook call is currently bypassed.
  2531. }
  2532.  
  2533. return result;
  2534.  
  2535. }
  2536. #pragma auto_inline()
  2537.  
  2538. // This function cannot be called like a normal function. It changes its
  2539. // calling convention at run-time and removes and extra argument from the stack.
  2540. __declspec(naked) int lua_sethook_intercept(unsigned long api, lua_State *L, lua_Hook f, int mask, int count)
  2541. {
  2542.  
  2543. int result;
  2544. bool stdcall;
  2545.  
  2546. INTERCEPT_PROLOG()
  2547.  
  2548. // We push the actual functionality of this function into a separate, "normal"
  2549. // function so avoid interferring with the inline assembly and other strange
  2550. // aspects of this function.
  2551. result = lua_sethook_worker(api, L, f, mask, count, stdcall);
  2552.  
  2553. INTERCEPT_EPILOG(16)
  2554.  
  2555. }
  2556.  
  2557. #pragma auto_inline(off)
  2558. int luaL_loadbuffer_worker(unsigned long api, lua_State *L, const char *buff, size_t sz, const char *name, bool& stdcall)
  2559. {
  2560.  
  2561. int result = 0;
  2562.  
  2563. if (!g_interfaces[api].finishedLoading)
  2564. {
  2565. stdcall = GetIsStdCallConvention(g_interfaces[api].luaL_loadbuffer_dll_cdecl, L, (void*)buff, (void*)sz, (void*)name, (void**)&result);
  2566. FinishLoadingLua(api, stdcall);
  2567. }
  2568. else if (g_interfaces[api].luaL_loadbuffer_dll_cdecl != NULL)
  2569. {
  2570. result = g_interfaces[api].luaL_loadbuffer_dll_cdecl(L, buff, sz, name);
  2571. stdcall = false;
  2572. }
  2573. else if (g_interfaces[api].luaL_loadbuffer_dll_stdcall != NULL)
  2574. {
  2575. result = g_interfaces[api].luaL_loadbuffer_dll_stdcall(L, buff, sz, name);
  2576. stdcall = true;
  2577. }
  2578.  
  2579. // Make sure the debugger knows about this state. This is necessary since we might have
  2580. // attached the debugger after the state was created.
  2581. DebugBackend::Get().AttachState(api, L);
  2582.  
  2583. return DebugBackend::Get().PostLoadScript(api, result, L, buff, sz, name);
  2584.  
  2585. }
  2586. #pragma auto_inline()
  2587.  
  2588. // This function cannot be called like a normal function. It changes its
  2589. // calling convention at run-time and removes and extra argument from the stack.
  2590. __declspec(naked) int luaL_loadbuffer_intercept(unsigned long api, lua_State *L, const char *buff, size_t sz, const char *name)
  2591. {
  2592.  
  2593. int result;
  2594. bool stdcall;
  2595.  
  2596. INTERCEPT_PROLOG()
  2597.  
  2598. // We push the actual functionality of this function into a separate, "normal"
  2599. // function so avoid interferring with the inline assembly and other strange
  2600. // aspects of this function.
  2601. result = luaL_loadbuffer_worker(api, L, buff, sz, name, stdcall);
  2602.  
  2603. INTERCEPT_EPILOG(16)
  2604.  
  2605. }
  2606.  
  2607. #pragma auto_inline(off)
  2608. int luaL_loadfile_worker(unsigned long api, lua_State *L, const char *fileName, bool& stdcall)
  2609. {
  2610.  
  2611. int result = 0;
  2612.  
  2613. if (!g_interfaces[api].finishedLoading)
  2614. {
  2615. stdcall = GetIsStdCallConvention(g_interfaces[api].luaL_loadfile_dll_cdecl, L, (void*)fileName, (void**)&result);
  2616. FinishLoadingLua(api, stdcall);
  2617. }
  2618. else if (g_interfaces[api].luaL_loadfile_dll_cdecl != NULL)
  2619. {
  2620. result = g_interfaces[api].luaL_loadfile_dll_cdecl(L, fileName);
  2621. stdcall = false;
  2622. }
  2623. else if (g_interfaces[api].luaL_loadfile_dll_stdcall != NULL)
  2624. {
  2625. result = g_interfaces[api].luaL_loadfile_dll_stdcall(L, fileName);
  2626. stdcall = true;
  2627. }
  2628.  
  2629. // Make sure the debugger knows about this state. This is necessary since we might have
  2630. // attached the debugger after the state was created.
  2631. DebugBackend::Get().AttachState(api, L);
  2632.  
  2633. // Load the file.
  2634.  
  2635. FILE* file = fopen(fileName, "rb");
  2636.  
  2637. if (file != NULL)
  2638. {
  2639.  
  2640. std::string name = "@";
  2641. name += fileName;
  2642.  
  2643. fseek(file, 0, SEEK_END);
  2644. unsigned int length = ftell(file);
  2645.  
  2646. char* buffer = new char[length];
  2647. fseek(file, 0, SEEK_SET);
  2648. fread(buffer, 1, length, file);
  2649.  
  2650. fclose(file);
  2651.  
  2652. result = DebugBackend::Get().PostLoadScript(api, result, L, buffer, length, name.c_str());
  2653.  
  2654. delete [] buffer;
  2655.  
  2656. }
  2657.  
  2658. return result;
  2659.  
  2660. }
  2661. #pragma auto_inline()
  2662.  
  2663. // This function cannot be called like a normal function. It changes its
  2664. // calling convention at run-time and removes and extra argument from the stack.
  2665. __declspec(naked) int luaL_loadfile_intercept(unsigned long api, lua_State *L, const char *fileName)
  2666. {
  2667.  
  2668. int result;
  2669. bool stdcall;
  2670.  
  2671. INTERCEPT_PROLOG()
  2672.  
  2673. // We push the actual functionality of this function into a separate, "normal"
  2674. // function so avoid interferring with the inline assembly and other strange
  2675. // aspects of this function.
  2676. result = luaL_loadfile_worker(api, L, fileName, stdcall);
  2677.  
  2678. INTERCEPT_EPILOG(8)
  2679.  
  2680. }
  2681.  
  2682. #pragma auto_inline(off)
  2683. lua_State* luaL_newstate_worker(unsigned long api, bool& stdcall)
  2684. {
  2685.  
  2686. lua_State* result = NULL;
  2687.  
  2688. if (g_interfaces[api].luaL_newstate_dll_cdecl != NULL)
  2689. {
  2690. result = g_interfaces[api].luaL_newstate_dll_cdecl();
  2691. }
  2692. else if (g_interfaces[api].luaL_newstate_dll_stdcall != NULL)
  2693. {
  2694. result = g_interfaces[api].luaL_newstate_dll_stdcall();
  2695. }
  2696.  
  2697. // Since we couldn't test if luaL_newstate was stdcall or cdecl (since it
  2698. // doesn't have any arguments), call another function. lua_gettop is a good
  2699. // choice since it has no side effects.
  2700.  
  2701. if (!g_interfaces[api].finishedLoading && result != NULL)
  2702. {
  2703. stdcall = GetIsStdCallConvention(g_interfaces[api].lua_gettop_dll_cdecl, result, NULL);
  2704. FinishLoadingLua(api, stdcall);
  2705. }
  2706.  
  2707. if (result != NULL)
  2708. {
  2709. DebugBackend::Get().AttachState(api, result);
  2710. }
  2711.  
  2712. return result;
  2713.  
  2714. }
  2715. #pragma auto_inline()
  2716.  
  2717. // This function cannot be called like a normal function. It changes its
  2718. // calling convention at run-time and removes and extra argument from the stack.
  2719. __declspec(naked) lua_State* luaL_newstate_intercept(unsigned long api)
  2720. {
  2721.  
  2722. lua_State* result;
  2723. bool stdcall;
  2724.  
  2725. INTERCEPT_PROLOG()
  2726.  
  2727. // We push the actual functionality of this function into a separate, "normal"
  2728. // function so avoid interferring with the inline assembly and other strange
  2729. // aspects of this function.
  2730. result = luaL_newstate_worker(api, stdcall);
  2731.  
  2732. INTERCEPT_EPILOG(0)
  2733.  
  2734. }
  2735.  
  2736. std::string GetEnvironmentVariable(const std::string& name)
  2737. {
  2738.  
  2739. DWORD size = ::GetEnvironmentVariable(name.c_str(), NULL, 0);
  2740.  
  2741. std::string result;
  2742.  
  2743. if (size > 0)
  2744. {
  2745.  
  2746. char* buffer = new char[size];
  2747. buffer[0] = 0;
  2748.  
  2749. GetEnvironmentVariable(name.c_str(), buffer, size);
  2750.  
  2751. result = buffer;
  2752. delete [] buffer;
  2753.  
  2754. }
  2755.  
  2756. return result;
  2757.  
  2758. }
  2759.  
  2760. std::string GetApplicationDirectory()
  2761. {
  2762.  
  2763. char fileName[_MAX_PATH];
  2764. GetModuleFileNameEx(GetCurrentProcess(), NULL, fileName, _MAX_PATH);
  2765.  
  2766. char* term = strrchr(fileName, '\\');
  2767.  
  2768. if (term != NULL)
  2769. {
  2770. *term = 0;
  2771. }
  2772.  
  2773. return fileName;
  2774.  
  2775. }
  2776.  
  2777. bool LoadLuaFunctions(const stdext::hash_map<std::string, DWORD64>& symbols, HANDLE hProcess)
  2778. {
  2779.  
  2780. #define GET_FUNCTION_OPTIONAL(function) \
  2781. { \
  2782. stdext::hash_map<std::string, DWORD64>::const_iterator iterator = symbols.find(#function); \
  2783. if (iterator != symbols.end()) \
  2784. { \
  2785. luaInterface.function##_dll_cdecl = reinterpret_cast<function##_cdecl_t>(iterator->second); \
  2786. } \
  2787. }
  2788.  
  2789. #define GET_FUNCTION(function) \
  2790. GET_FUNCTION_OPTIONAL(function) \
  2791. if (luaInterface.function##_dll_cdecl == NULL) \
  2792. { \
  2793. if (report) \
  2794. { \
  2795. DebugBackend::Get().Message("Warning 1004: Couldn't hook Lua function '" #function "'", MessageType_Warning); \
  2796. } \
  2797. return false; \
  2798. }
  2799.  
  2800. #define HOOK_FUNCTION(function) \
  2801. if (luaInterface.function##_dll_cdecl != NULL) \
  2802. { \
  2803. void* original = luaInterface.function##_dll_cdecl; \
  2804. luaInterface.function##_dll_cdecl = (function##_cdecl_t)(HookFunction(original, function##_intercept, api)); \
  2805. }
  2806.  
  2807. LuaInterface luaInterface = { 0 };
  2808. luaInterface.finishedLoading = false;
  2809. luaInterface.stdcall = false;
  2810.  
  2811. unsigned long api = g_interfaces.size();
  2812.  
  2813. bool report = false;
  2814.  
  2815. // Check if the lua_tag function exists. This function is only in Lua 4.0 and not in Lua 5.0.
  2816. // This helps us differentiate between those two versions.
  2817.  
  2818. luaInterface.registryIndex = 0;
  2819. luaInterface.globalsIndex = 0;
  2820.  
  2821. if (symbols.find("lua_tag") != symbols.end())
  2822. {
  2823. luaInterface.version = 401;
  2824. }
  2825. else
  2826. {
  2827. if (symbols.find("lua_open") != symbols.end())
  2828. {
  2829. luaInterface.version = 500;
  2830. luaInterface.registryIndex = -10000;
  2831. luaInterface.globalsIndex = -10001;
  2832. }
  2833. else if (symbols.find("lua_callk") != symbols.end())
  2834. {
  2835. luaInterface.version = 520;
  2836. luaInterface.registryIndex = -10000;
  2837. luaInterface.globalsIndex = -10001;
  2838. }
  2839. else
  2840. {
  2841. luaInterface.version = 510;
  2842. luaInterface.registryIndex = -10000;
  2843. luaInterface.globalsIndex = -10002;
  2844. }
  2845.  
  2846. }
  2847.  
  2848. // Only present in Lua 4.0 and Lua 5.0 (not 5.1)
  2849. GET_FUNCTION_OPTIONAL(lua_open);
  2850. if (luaInterface.lua_open_dll_cdecl == NULL)
  2851. {
  2852. GET_FUNCTION(lua_newstate);
  2853. }
  2854.  
  2855. // Start reporting errors about functions we couldn't hook.
  2856. report = true;
  2857.  
  2858. GET_FUNCTION(lua_newthread);
  2859. GET_FUNCTION(lua_close);
  2860. GET_FUNCTION(lua_error);
  2861. GET_FUNCTION(lua_sethook);
  2862. GET_FUNCTION(lua_getinfo);
  2863. GET_FUNCTION(lua_remove);
  2864. GET_FUNCTION(lua_settable);
  2865. GET_FUNCTION(lua_gettable);
  2866. GET_FUNCTION(lua_rawget);
  2867. GET_FUNCTION(lua_rawgeti);
  2868. GET_FUNCTION(lua_rawset);
  2869. GET_FUNCTION(lua_pushstring);
  2870. GET_FUNCTION(lua_pushlstring);
  2871. GET_FUNCTION(lua_type);
  2872. GET_FUNCTION(lua_typename);
  2873. GET_FUNCTION(lua_settop);
  2874. GET_FUNCTION(lua_gettop);
  2875. GET_FUNCTION(lua_getlocal);
  2876. GET_FUNCTION(lua_setlocal);
  2877. GET_FUNCTION(lua_getstack);
  2878. GET_FUNCTION(lua_insert);
  2879. GET_FUNCTION(lua_pushnil);
  2880. GET_FUNCTION(lua_pushvalue);
  2881. GET_FUNCTION(lua_pushcclosure);
  2882. GET_FUNCTION(lua_pushnumber);
  2883. GET_FUNCTION(lua_pushlightuserdata);
  2884. GET_FUNCTION(lua_checkstack);
  2885.  
  2886. // Only present in Lua 5.1 (*number funtions used in Lua 4.0)
  2887. GET_FUNCTION_OPTIONAL(lua_pushinteger);
  2888. GET_FUNCTION_OPTIONAL(lua_tointeger);
  2889. GET_FUNCTION_OPTIONAL(lua_tointegerx);
  2890.  
  2891. // Only present in Lua 4.0 and 5.0 (exists as a macro in Lua 5.1)
  2892. GET_FUNCTION_OPTIONAL(lua_tostring);
  2893.  
  2894. if (luaInterface.lua_tostring_dll_cdecl == NULL)
  2895. {
  2896. GET_FUNCTION(lua_tolstring);
  2897. }
  2898.  
  2899. GET_FUNCTION_OPTIONAL(lua_tonumberx);
  2900.  
  2901. if (luaInterface.lua_tonumberx_dll_cdecl == NULL)
  2902. {
  2903. // If the Lua 5.2 tonumber isn't present, require the previous version.
  2904. GET_FUNCTION(lua_tonumber);
  2905. }
  2906.  
  2907. GET_FUNCTION(lua_toboolean);
  2908. GET_FUNCTION(lua_tocfunction);
  2909. GET_FUNCTION(lua_touserdata);
  2910.  
  2911. // Exists as a macro in Lua 5.2
  2912. GET_FUNCTION_OPTIONAL(lua_callk);
  2913. if (luaInterface.lua_callk_dll_cdecl == NULL)
  2914. {
  2915. GET_FUNCTION(lua_call);
  2916. }
  2917.  
  2918. // Exists as a macro in Lua 5.2
  2919. GET_FUNCTION_OPTIONAL(lua_pcallk);
  2920. if (luaInterface.lua_pcallk_dll_cdecl == NULL)
  2921. {
  2922. GET_FUNCTION(lua_pcall);
  2923. }
  2924.  
  2925. // Only present in Lua 4.0 and 5.0 (exists as a macro in Lua 5.1)
  2926. GET_FUNCTION_OPTIONAL(lua_newtable);
  2927. if (luaInterface.lua_newtable_dll_cdecl == NULL)
  2928. {
  2929. GET_FUNCTION(lua_createtable);
  2930. }
  2931.  
  2932. GET_FUNCTION(lua_load);
  2933. GET_FUNCTION(lua_next);
  2934. GET_FUNCTION(lua_rawequal);
  2935. GET_FUNCTION(lua_getmetatable);
  2936. GET_FUNCTION(lua_setmetatable);
  2937. GET_FUNCTION_OPTIONAL(luaL_ref);
  2938. GET_FUNCTION_OPTIONAL(luaL_unref);
  2939. GET_FUNCTION(luaL_newmetatable);
  2940. GET_FUNCTION(lua_getupvalue);
  2941. GET_FUNCTION(lua_setupvalue);
  2942.  
  2943. // We don't currently need these.
  2944. GET_FUNCTION_OPTIONAL(lua_getfenv);
  2945. GET_FUNCTION_OPTIONAL(lua_setfenv);
  2946. GET_FUNCTION_OPTIONAL(lua_cpcall);
  2947.  
  2948. if (luaInterface.version >= 510)
  2949. {
  2950. GET_FUNCTION(lua_pushthread);
  2951. }
  2952. else
  2953. {
  2954. // This function doesn't exist in Lua 5.0, so make it optional.
  2955. GET_FUNCTION_OPTIONAL(lua_pushthread);
  2956. }
  2957.  
  2958. GET_FUNCTION(lua_newuserdata);
  2959.  
  2960. // This function isn't strictly necessary. We only hook it
  2961. // in case the base function was inlined.
  2962. GET_FUNCTION_OPTIONAL(luaL_newstate);
  2963. GET_FUNCTION_OPTIONAL(luaL_loadbuffer);
  2964. GET_FUNCTION_OPTIONAL(luaL_loadfile);
  2965.  
  2966. // These functions only exists in LuaPlus.
  2967. GET_FUNCTION_OPTIONAL(lua_towstring);
  2968. GET_FUNCTION_OPTIONAL(lua_iswstring);
  2969.  
  2970. // Hook the functions we need to intercept calls to.
  2971.  
  2972. if (luaInterface.version == 500)
  2973. {
  2974. luaInterface.lua_open_500_dll_cdecl = reinterpret_cast<lua_open_500_cdecl_t>(luaInterface.lua_open_dll_cdecl);
  2975. luaInterface.lua_open_dll_cdecl = NULL;
  2976. }
  2977.  
  2978. HOOK_FUNCTION(lua_open);
  2979. HOOK_FUNCTION(lua_open_500);
  2980. HOOK_FUNCTION(lua_newstate);
  2981. HOOK_FUNCTION(lua_close);
  2982. HOOK_FUNCTION(lua_newthread);
  2983. HOOK_FUNCTION(lua_pcall);
  2984. HOOK_FUNCTION(lua_pcallk);
  2985. HOOK_FUNCTION(lua_call);
  2986. HOOK_FUNCTION(lua_callk);
  2987. HOOK_FUNCTION(lua_load);
  2988. HOOK_FUNCTION(luaL_newmetatable);
  2989. HOOK_FUNCTION(lua_sethook);
  2990.  
  2991. HOOK_FUNCTION(luaL_loadbuffer);
  2992. HOOK_FUNCTION(luaL_loadfile);
  2993. HOOK_FUNCTION(luaL_newstate);
  2994.  
  2995. #ifdef VERBOSE
  2996. DebugBackend::Get().Message("Found all necessary Lua functions");
  2997. #endif
  2998.  
  2999. // Setup our API.
  3000.  
  3001. luaInterface.DecodaOutput = (lua_CFunction)InstanceFunction(DecodaOutput, api);
  3002. luaInterface.CPCallHandler = (lua_CFunction)InstanceFunction(CPCallHandler, api);
  3003. luaInterface.HookHandler = (lua_Hook)InstanceFunction(HookHandler, api);
  3004.  
  3005. g_interfaces.push_back( luaInterface );
  3006.  
  3007. if (!g_loadedLuaFunctions)
  3008. {
  3009. DebugBackend::Get().Message("Debugger attached to process");
  3010. g_loadedLuaFunctions = true;
  3011. }
  3012.  
  3013. return true;
  3014.  
  3015. }
  3016.  
  3017. static PIMAGE_NT_HEADERS PEHeaderFromHModule(HMODULE hModule)
  3018. {
  3019. PIMAGE_NT_HEADERS pNTHeader = 0;
  3020.  
  3021. __try
  3022. {
  3023. if ( PIMAGE_DOS_HEADER(hModule)->e_magic != IMAGE_DOS_SIGNATURE )
  3024. __leave;
  3025.  
  3026. pNTHeader = PIMAGE_NT_HEADERS(PBYTE(hModule)
  3027. + PIMAGE_DOS_HEADER(hModule)->e_lfanew);
  3028.  
  3029. if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
  3030. pNTHeader = 0;
  3031. }
  3032. __except( EXCEPTION_EXECUTE_HANDLER )
  3033. {
  3034. }
  3035.  
  3036. return pNTHeader;
  3037. }
  3038.  
  3039. /**
  3040. * Gets a list of the files that are imported by a module.
  3041. */
  3042. bool GetModuleImports(HANDLE hProcess, HMODULE hModule, std::vector<std::string>& imports)
  3043. {
  3044.  
  3045. PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule( hModule );
  3046.  
  3047. if ( !pExeNTHdr )
  3048. {
  3049. return false;
  3050. }
  3051.  
  3052. DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory
  3053. [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  3054. if ( !importRVA )
  3055. {
  3056. return false;
  3057. }
  3058.  
  3059. // Convert imports RVA to a usable pointer
  3060. PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MAKE_PTR( PIMAGE_IMPORT_DESCRIPTOR,
  3061. hModule, importRVA );
  3062.  
  3063. // Iterate through each import descriptor, and redirect if appropriate
  3064. while ( pImportDesc->FirstThunk )
  3065. {
  3066. PSTR pszImportModuleName = MAKE_PTR( PSTR, hModule, pImportDesc->Name);
  3067. imports.push_back(pszImportModuleName);
  3068. pImportDesc++; // Advance to next import descriptor
  3069. }
  3070.  
  3071. return true;
  3072. }
  3073.  
  3074. bool GetFileExists(const char* fileName)
  3075. {
  3076. return GetFileAttributes(fileName) != INVALID_FILE_ATTRIBUTES;
  3077. }
  3078.  
  3079. void ReplaceExtension(char fileName[_MAX_PATH], const char* extension)
  3080. {
  3081.  
  3082. char* start = strrchr(fileName, '.');
  3083.  
  3084. if (start == NULL)
  3085. {
  3086. strcat(fileName, extension);
  3087. }
  3088. else
  3089. {
  3090. strcpy(start + 1, extension);
  3091. }
  3092.  
  3093. }
  3094.  
  3095. void GetFileTitle(const char* fileName, char fileTitle[_MAX_PATH])
  3096. {
  3097.  
  3098. const char* slash1 = strrchr(fileName, '\\');
  3099. const char* slash2 = strrchr(fileName, '/');
  3100.  
  3101. const char* pathEnd = max(slash1, slash2);
  3102.  
  3103. if (pathEnd == NULL)
  3104. {
  3105. // There's no path so the whole thing is the file title.
  3106. strcpy(fileTitle, fileName);
  3107. }
  3108. else
  3109. {
  3110. strcpy(fileTitle, pathEnd + 1);
  3111. }
  3112.  
  3113. }
  3114.  
  3115. void GetFilePath(const char* fileName, char path[_MAX_PATH])
  3116. {
  3117.  
  3118. const char* slash1 = strrchr(fileName, '\\');
  3119. const char* slash2 = strrchr(fileName, '/');
  3120.  
  3121. const char* pathEnd = max(slash1, slash2);
  3122.  
  3123. if (pathEnd == NULL)
  3124. {
  3125. // There's no path on the file name.
  3126. path[0] = 0;
  3127. }
  3128. else
  3129. {
  3130. size_t length = pathEnd - fileName + 1;
  3131. memcpy(path, fileName, length);
  3132. path[length] = 0;
  3133. }
  3134.  
  3135. }
  3136.  
  3137. bool LocateSymbolFile(const IMAGEHLP_MODULE64& moduleInfo, char fileName[_MAX_PATH])
  3138. {
  3139.  
  3140. // The search order for symbol files is described here:
  3141. // http://msdn2.microsoft.com/en-us/library/ms680689.aspx
  3142.  
  3143. // This function doesn't currently support the full spec.
  3144.  
  3145. const char* imageFileName = moduleInfo.LoadedImageName;
  3146.  
  3147. // First check the absolute path specified in the CodeView data.
  3148. if (GetFileExists(moduleInfo.CVData))
  3149. {
  3150. strncpy(fileName, moduleInfo.CVData, _MAX_PATH);
  3151. return true;
  3152. }
  3153.  
  3154. char symbolTitle[_MAX_PATH];
  3155. GetFileTitle(moduleInfo.CVData, symbolTitle);
  3156.  
  3157. // Now check in the same directory as the image.
  3158.  
  3159. char imagePath[_MAX_PATH];
  3160. GetFilePath(imageFileName, imagePath);
  3161.  
  3162. strcat(imagePath, symbolTitle);
  3163.  
  3164. if (GetFileExists(imagePath))
  3165. {
  3166. strncpy(fileName, imagePath, _MAX_PATH);
  3167. return true;
  3168. }
  3169.  
  3170. return false;
  3171.  
  3172. }
  3173.  
  3174. BOOL CALLBACK GatherSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
  3175. {
  3176.  
  3177. stdext::hash_map<std::string, DWORD64>* symbols = reinterpret_cast<stdext::hash_map<std::string, DWORD64>*>(UserContext);
  3178.  
  3179. if (pSymInfo != NULL && pSymInfo->Name != NULL)
  3180. {
  3181. symbols->insert(std::make_pair(pSymInfo->Name, pSymInfo->Address));
  3182. }
  3183.  
  3184. return TRUE;
  3185.  
  3186. }
  3187.  
  3188. BOOL CALLBACK FindSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
  3189. {
  3190. bool* found = reinterpret_cast<bool*>(UserContext);
  3191. *found = true;
  3192. return FALSE;
  3193. }
  3194.  
  3195. bool ScanForSignature(DWORD64 start, DWORD64 length, const char* signature)
  3196. {
  3197.  
  3198. unsigned int signatureLength = strlen(signature);
  3199.  
  3200. for (DWORD64 i = start; i < start + length - signatureLength; ++i)
  3201. {
  3202.  
  3203. void* p = reinterpret_cast<void*>(i);
  3204.  
  3205. // Check that we have read access to the data. For some reason under Windows
  3206. // Vista part of the DLL is not accessible (possibly some sort of new delay
  3207. // loading mechanism for DLLs?)
  3208. if (IsBadReadPtr(reinterpret_cast<LPCSTR>(p), signatureLength))
  3209. {
  3210. break;
  3211. }
  3212.  
  3213. if (memcmp(p, signature, signatureLength) == 0)
  3214. {
  3215. return true;
  3216. }
  3217.  
  3218. }
  3219.  
  3220. return false;
  3221.  
  3222. }
  3223.  
  3224. void LoadSymbolsRecursively(std::set<std::string>& loadedModules, stdext::hash_map<std::string, DWORD64>& symbols, HANDLE hProcess, HMODULE hModule)
  3225. {
  3226.  
  3227. assert(hModule != NULL);
  3228.  
  3229. char moduleName[_MAX_PATH];
  3230. GetModuleBaseName(hProcess, hModule, moduleName, _MAX_PATH);
  3231.  
  3232. if (loadedModules.find(moduleName) == loadedModules.end())
  3233. {
  3234.  
  3235. // Record that we've loaded this module so that we don't
  3236. // try to load it again.
  3237. loadedModules.insert(moduleName);
  3238.  
  3239. MODULEINFO moduleInfo = { 0 };
  3240. GetModuleInformation(hProcess, hModule, &moduleInfo, sizeof(moduleInfo));
  3241.  
  3242. char moduleFileName[_MAX_PATH];
  3243. GetModuleFileNameEx(hProcess, hModule, moduleFileName, _MAX_PATH);
  3244.  
  3245. DWORD64 base = SymLoadModule64_dll(hProcess, NULL, moduleFileName, moduleName, (DWORD64)moduleInfo.lpBaseOfDll, moduleInfo.SizeOfImage);
  3246.  
  3247. #ifdef VERBOSE
  3248. char message[1024];
  3249. _snprintf(message, 1024, "Examining '%s' %s\n", moduleName, base ? "(symbols loaded)" : "");
  3250. DebugBackend::Get().Log(message);
  3251. #endif
  3252.  
  3253. // Check to see if there was a symbol file we failed to load (usually
  3254. // becase it didn't match the version of the module).
  3255.  
  3256. IMAGEHLP_MODULE64 module;
  3257. memset(&module, 0, sizeof(module));
  3258. module.SizeOfStruct = sizeof(module);
  3259.  
  3260. BOOL result = SymGetModuleInfo64_dll(hProcess, base, &module);
  3261.  
  3262. if (result && module.SymType == SymNone)
  3263. {
  3264.  
  3265. // No symbols were found. Check to see if the module file name + ".pdb"
  3266. // exists, since the symbol file and/or module names may have been renamed.
  3267.  
  3268. char pdbFileName[_MAX_PATH];
  3269. strcpy(pdbFileName, moduleFileName);
  3270. ReplaceExtension(pdbFileName, "pdb");
  3271.  
  3272. if (GetFileExists(pdbFileName))
  3273. {
  3274.  
  3275. SymUnloadModule64_dll(hProcess, base);
  3276. base = SymLoadModule64_dll(hProcess, NULL, pdbFileName, moduleName, (DWORD64)moduleInfo.lpBaseOfDll, moduleInfo.SizeOfImage);
  3277.  
  3278. if (base != 0)
  3279. {
  3280. result = SymGetModuleInfo64_dll(hProcess, base, &module);
  3281. }
  3282. else
  3283. {
  3284. result = FALSE;
  3285. }
  3286.  
  3287. }
  3288.  
  3289. }
  3290.  
  3291. if (result)
  3292. {
  3293.  
  3294. // Check to see if we've already warned about this module.
  3295. if (g_warnedAboutPdb.find(moduleFileName) == g_warnedAboutPdb.end())
  3296. {
  3297. if (strlen(module.CVData) > 0 && (module.SymType == SymExport || module.SymType == SymNone))
  3298. {
  3299.  
  3300. char symbolFileName[_MAX_PATH];
  3301.  
  3302. if (LocateSymbolFile(module, symbolFileName))
  3303. {
  3304. char message[1024];
  3305. _snprintf(message, 1024, "Warning 1002: Symbol file '%s' located but it does not match module '%s'", symbolFileName, moduleFileName);
  3306. DebugBackend::Get().Message(message, MessageType_Warning);
  3307. }
  3308.  
  3309. // Remember that we've checked on this file, so no need to check again.
  3310. g_warnedAboutPdb.insert(moduleFileName);
  3311.  
  3312. }
  3313. }
  3314.  
  3315. }
  3316.  
  3317. if (base != 0)
  3318. {
  3319. // SymFromName is really slow, so we gather up our own list of the symbols that we
  3320. // can index much faster.
  3321. SymEnumSymbols_dll(hProcess, base, "lua*", GatherSymbolsCallback, reinterpret_cast<PVOID>(&symbols));
  3322. }
  3323.  
  3324. // Check to see if the module contains the Lua signature but we didn't find any Lua functions.
  3325.  
  3326. if (g_warnedAboutLua.find(moduleFileName) == g_warnedAboutLua.end())
  3327. {
  3328.  
  3329. // Check to see if this module contains any Lua functions loaded from the symbols.
  3330.  
  3331. bool foundLuaFunctions = false;
  3332.  
  3333. if (base != 0)
  3334. {
  3335. SymEnumSymbols_dll(hProcess, base, "lua_*", FindSymbolsCallback, &foundLuaFunctions);
  3336. }
  3337.  
  3338. if (!foundLuaFunctions)
  3339. {
  3340.  
  3341. // Check to see if this module contains a string from the Lua source code. If it's there, it probably
  3342. // means this module has Lua compiled into it.
  3343.  
  3344. bool luaFile = ScanForSignature((DWORD64)hModule, moduleInfo.SizeOfImage, "$Lua:");
  3345.  
  3346. if (luaFile)
  3347. {
  3348. char message[1024];
  3349. _snprintf(message, 1024, "Warning 1001: '%s' appears to contain Lua functions however no Lua functions could located with the symbolic information", moduleFileName);
  3350. DebugBackend::Get().Message(message, MessageType_Warning);
  3351. }
  3352.  
  3353. }
  3354.  
  3355. // Remember that we've checked on this file, so no need to check again.
  3356. g_warnedAboutLua.insert(moduleFileName);
  3357.  
  3358. }
  3359.  
  3360. // Get the imports for the module. These are loaded before we're able to hook
  3361. // LoadLibrary for the module.
  3362.  
  3363. std::vector<std::string> imports;
  3364. GetModuleImports(hProcess, hModule, imports);
  3365.  
  3366. for (unsigned int i = 0; i < imports.size(); ++i)
  3367. {
  3368.  
  3369. HMODULE hImportModule = GetModuleHandle(imports[i].c_str());
  3370.  
  3371. // Sometimes the import module comes back NULL, which means that for some reason
  3372. // it wasn't loaded. Perhaps these are delay loaded and we'll catch them later?
  3373. if (hImportModule != NULL)
  3374. {
  3375. LoadSymbolsRecursively(loadedModules, symbols, hProcess, hImportModule);
  3376. }
  3377.  
  3378. }
  3379.  
  3380. }
  3381.  
  3382. }
  3383.  
  3384. BOOL CALLBACK SymbolCallbackFunction(HANDLE hProcess, ULONG code, ULONG64 data, ULONG64 UserContext)
  3385. {
  3386.  
  3387. if (code == CBA_DEBUG_INFO)
  3388. {
  3389. DebugBackend::Get().Message(reinterpret_cast<char*>(data));
  3390. }
  3391.  
  3392. return TRUE;
  3393.  
  3394. }
  3395.  
  3396. void PostLoadLibrary(HMODULE hModule)
  3397. {
  3398.  
  3399. extern HINSTANCE g_hInstance;
  3400.  
  3401. if (hModule == g_hInstance)
  3402. {
  3403. // Don't investigate ourself.
  3404. return;
  3405. }
  3406.  
  3407. HANDLE hProcess = GetCurrentProcess();
  3408.  
  3409. char moduleName[_MAX_PATH];
  3410. GetModuleBaseName(hProcess, hModule, moduleName, _MAX_PATH);
  3411.  
  3412. CriticalSectionLock lock(g_loadedModulesCriticalSection);
  3413.  
  3414. if (g_loadedModules.find(moduleName) == g_loadedModules.end())
  3415. {
  3416.  
  3417. // Record that we've loaded this module so that we don't
  3418. // try to load it again.
  3419. g_loadedModules.insert(moduleName);
  3420.  
  3421. if (!g_initializedDebugHelp)
  3422. {
  3423. if (!SymInitialize_dll(hProcess, g_symbolsDirectory.c_str(), FALSE))
  3424. {
  3425. return;
  3426. }
  3427. g_initializedDebugHelp = true;
  3428. }
  3429.  
  3430. //SymSetOptions(SYMOPT_DEBUG);
  3431.  
  3432. std::set<std::string> loadedModules;
  3433. stdext::hash_map<std::string, DWORD64> symbols;
  3434.  
  3435. LoadSymbolsRecursively(loadedModules, symbols, hProcess, hModule);
  3436.  
  3437. LoadLuaFunctions(symbols, hProcess);
  3438.  
  3439. //SymCleanup_dll(hProcess);
  3440. //hProcess = NULL;
  3441.  
  3442. }
  3443.  
  3444. }
  3445.  
  3446. void HookLoadLibrary()
  3447. {
  3448.  
  3449. HMODULE hModuleKernel = GetModuleHandle("kernel32.dll");
  3450.  
  3451. if (hModuleKernel != NULL)
  3452. {
  3453. // LoadLibraryExW is called by the other LoadLibrary functions, so we
  3454. // only need to hook it.
  3455. LoadLibraryExW_dll = (LoadLibraryExW_t) HookFunction( GetProcAddress(hModuleKernel, "LoadLibraryExW"), LoadLibraryExW_intercept);
  3456. }
  3457.  
  3458. // These NTDLL functions are undocumented and don't exist in Windows 2000.
  3459.  
  3460. HMODULE hModuleNt = GetModuleHandle("ntdll.dll");
  3461.  
  3462. if (hModuleNt != NULL)
  3463. {
  3464. LdrLockLoaderLock_dll = (LdrLockLoaderLock_t) GetProcAddress(hModuleNt, "LdrLockLoaderLock");
  3465. LdrUnlockLoaderLock_dll = (LdrUnlockLoaderLock_t) GetProcAddress(hModuleNt, "LdrUnlockLoaderLock");
  3466. }
  3467.  
  3468. }
  3469.  
  3470. bool InstallLuaHooker(HINSTANCE hInstance, const char* symbolsDirectory)
  3471. {
  3472.  
  3473. // Load the dbghelp functions. We have to do this dynamically since the
  3474. // older version of dbghelp that ships with Windows doesn't successfully
  3475. // load the symbols from PDBs. We can't simply include our new DLL since
  3476. // it needs to be in the directory for the application we're *debugging*
  3477. // since this DLL is injected.
  3478. if (!LoadDebugHelp(hInstance))
  3479. {
  3480. return false;
  3481. }
  3482.  
  3483. g_symbolsDirectory = symbolsDirectory;
  3484.  
  3485. // Add the "standard" stuff to the symbols directory search path.
  3486. g_symbolsDirectory += ";" + GetApplicationDirectory();
  3487. g_symbolsDirectory += ";" + GetEnvironmentVariable("_NT_SYMBOL_PATH");
  3488. g_symbolsDirectory += ";" + GetEnvironmentVariable("_NT_ALTERNATE_SYMBOL_PATH");
  3489.  
  3490. // Hook LoadLibrary* functions so that we can intercept those calls and search
  3491. // for Lua functions.
  3492. HookLoadLibrary();
  3493.  
  3494. // Avoid deadlock if a new DLL is loaded during this function.
  3495. ULONG cookie;
  3496.  
  3497. if (LdrLockLoaderLock_dll != NULL &&
  3498. LdrUnlockLoaderLock_dll != NULL)
  3499. {
  3500. LdrLockLoaderLock_dll(0, 0, &cookie);
  3501. }
  3502.  
  3503. // Process all of the loaded modules.
  3504.  
  3505. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
  3506.  
  3507. if (hSnapshot == NULL)
  3508. {
  3509.  
  3510. // If for some reason we couldn't take a snapshot, just load the
  3511. // main module. This shouldn't ever happen, but we do it just in
  3512. // case.
  3513. HMODULE hModule = GetModuleHandle(NULL);
  3514. PostLoadLibrary(hModule);
  3515.  
  3516. if (LdrLockLoaderLock_dll != NULL &&
  3517. LdrUnlockLoaderLock_dll != NULL)
  3518. {
  3519. LdrUnlockLoaderLock_dll(0, cookie);
  3520. }
  3521.  
  3522. return true;
  3523.  
  3524. }
  3525.  
  3526. MODULEENTRY32 module;
  3527. module.dwSize = sizeof(MODULEENTRY32);
  3528.  
  3529. BOOL moreModules = Module32First(hSnapshot, &module);
  3530.  
  3531. while (moreModules)
  3532. {
  3533. PostLoadLibrary(module.hModule);
  3534. moreModules = Module32Next(hSnapshot, &module);
  3535. }
  3536.  
  3537. CloseHandle(hSnapshot);
  3538. hSnapshot = NULL;
  3539.  
  3540. if (LdrLockLoaderLock_dll != NULL &&
  3541. LdrUnlockLoaderLock_dll != NULL)
  3542. {
  3543. LdrUnlockLoaderLock_dll(0, cookie);
  3544. }
  3545.  
  3546. return true;
  3547.  
  3548. }
  3549.  
  3550. bool GetIsLuaLoaded()
  3551. {
  3552. return g_loadedLuaFunctions;
  3553. }
  3554.  
  3555. bool GetIsStdCall(unsigned long api)
  3556. {
  3557. return g_interfaces[api].stdcall;
  3558. }
  3559.  
  3560. struct CFunctionArgs
  3561. {
  3562. unsigned long api;
  3563. lua_CFunction_dll function;
  3564. };
  3565.  
  3566. #pragma auto_inline(off)
  3567. int CFunctionHandlerWorker(CFunctionArgs* args, lua_State* L, bool& stdcall)
  3568. {
  3569. stdcall = g_interfaces[args->api].stdcall;
  3570. return args->function(args->api, L);
  3571. }
  3572. #pragma auto_inline()
  3573.  
  3574. __declspec(naked) int CFunctionHandler(CFunctionArgs* args, lua_State* L)
  3575. {
  3576.  
  3577. int result;
  3578. bool stdcall;
  3579.  
  3580. INTERCEPT_PROLOG()
  3581.  
  3582. stdcall = false;
  3583. result = CFunctionHandlerWorker(args, L, stdcall);
  3584.  
  3585. INTERCEPT_EPILOG(4)
  3586.  
  3587. }
  3588.  
  3589. lua_CFunction CreateCFunction(unsigned long api, lua_CFunction_dll function)
  3590. {
  3591.  
  3592. // This is never deallocated, but it doesn't really matter since we never
  3593. // destroy these functions.
  3594. CFunctionArgs* args = new CFunctionArgs;
  3595. args->api = api;
  3596. args->function = function;
  3597.  
  3598. return (lua_CFunction)InstanceFunction(CFunctionHandler, reinterpret_cast<unsigned long>(args));
  3599.  
  3600. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement