Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

906 lines
37 KiB

  1. // Copyright � 2008-, Valve LLC, All rigStahts reserved.
  2. //
  3. // cegclient.h
  4. //
  5. // This file is to be imported by client applications that wish to link with our DRM library !
  6. //
  7. // Performance Note :
  8. //
  9. // There are several points within cegclient.h where we'll place a 'Performance Note' to indicate
  10. // the potential performance consequences of particular CEG functions.
  11. //
  12. //
  13. //
  14. //
  15. // CEG Initialization -
  16. //
  17. // The first and last functions within the CEG SDK that must be called are :
  18. // Steamworks_InitCEGLibrary()
  19. // Steamworks_TermCEGLibrary()
  20. //
  21. // There are alternate versions of these functions, for people who restrict their usage of the
  22. // CEG SDK to a subset of the available API's (more on the subset later). These functions are :
  23. //
  24. // Steamworks_MinimumInitCEGLibrary()
  25. // Steamworks_MinimumTermCEGLibrary().
  26. //
  27. // In the event that the CEG library is initialized through Steamworks_InitCEGLibrary(), then the
  28. // following functions must also be called, on each thread on which CEG code may execute, before any
  29. // other CEG code code executes on the thread (these functions are not necessary if Steamworks_MinimumInitCEGLibrary() is called).
  30. //
  31. // Steamworks_RegisterThread()
  32. // Steamworks_UnRegisterThread().
  33. //
  34. // The only function which can be called before Steamworks_RegisterThread() is Steamworks_InitCEGLibrary().
  35. // Steamworks_RegisterThread() must be called on the thread that calls Steamworks_InitCEGLibrary(), if it calls any
  36. // other CEG functions.
  37. // For example, your main() will probably look like :
  38. //
  39. // int main( int argc, char* argv[] )
  40. // {
  41. // Steamworks_InitCEGLibrary();
  42. // Steamworks_RegisterThread();
  43. //
  44. // /* Real work here */
  45. //
  46. // Steamworks_UnRegisterThread();
  47. // Steamworks_TermCEGLibrary();
  48. // return 0;
  49. // }
  50. //
  51. //
  52. //
  53. // CEG Minimum API :
  54. //
  55. // Steamworks_SimpleCheck()
  56. //
  57. // This API is provided for people who are trying to combine CEG with other DRM technology.
  58. // This function does a very basic check that the machine is executing on the machine it was produced for.
  59. // This function doesn't conceal any of the data it is using to evaluate the machine, and therefore should not be
  60. // used with the full CEG SDK. It it not necessary to call Steamworks_RegisterThread()/Steamworks_UnRegisterThread()
  61. // if CEG API usage is restricted to this function.
  62. //
  63. // CEG Full API's :
  64. //
  65. // The full set of CEG API's takes the form of direct function calls, who's performance impacts may be easily analyzed
  66. // versus macros, which cause sophisticated manipulations of your .obj files before the final executable is linked.
  67. //
  68. //
  69. // Direct Functions Calls -
  70. // Steamworks_TestSecret()
  71. // Steamworks_TestSecretAlways(),
  72. // Steamorks_SelfCheck().
  73. //
  74. // Steamworks_TestSecret() and Steamworks_TestSecretAlways() are focused on evaluating the current
  75. // computer to determine whether it is the machine the binary was produced for.
  76. // Because a hacker may be 'tracing' all windows API calls with a tool such as sysinternal's Process Monitor
  77. // ( http://technet.microsoft.com/en-us/sysinternals/bb896645 ), Steamworks_TestSecret() will not always
  78. // evaluate it's secret. The intention is to make it harder to record CEG activity.
  79. // Steamworks_TestSecretAlways() will always evaluate it's portion of secret data.
  80. //
  81. // Steamworks_SelfCheck() - this function is focused on determining whether the executable has been modified.
  82. //
  83. //
  84. // Macro Mechanisms:
  85. //
  86. // CEG's macro mechanisms attempt to entwine machine specific information into the correct operation of the game
  87. // product. As a result, unlike CEG function calls (which a hacker can simply stub out), a hacker must
  88. // take the time to determine how the CEG code is entwined within the product, and make a more significant effort
  89. // to modify the game.
  90. //
  91. // Specific Macro Mechanisms:
  92. //
  93. // CEG_EncryptFunction()
  94. //
  95. // The function which contains this macro will be modified, so that the opcodes comprising the function
  96. // are encrypted within the executable file. The decryption key is derived from machine specific data.
  97. // If decryption of the code fails, the function will not be executed, and the game will to continue to run.
  98. // Whether the executable immediately terminates or not depends on what the encrypted function does for the game,
  99. // as well as calling convention and architecture issues, as the CEG code may not clean up the stack correctly
  100. // when the function fails to execute.
  101. // (Please note : Many CEG functions are themselves encrypted using this mechanism).
  102. //
  103. // This mechanism can be used an unlimited number of times - the following macros have restrictions on
  104. // the number of times they can be used within your executable.
  105. //
  106. // Performance Note :
  107. // Every time a function containing CEG_EncryptFunction() macro is invoked, CEG code must execute to
  108. // produce the function in a ready to run form in temporarily allocated memory.
  109. // CEG will keep a cached version of the function for up to 10 seconds, so that the full cost of decryption
  110. // is not paid on every invocation. However, every invocation does incur some CEG overhead to
  111. // either decrypt or locate the cached form and to properly martial the call to the decrypted form of the function.
  112. //
  113. //-----------------------------------------
  114. // CEG_ProtectFunction()
  115. //
  116. // The function which contains this macro will be modified, so that it's address must be computed
  117. // by every caller of the function. The address computation will involve machine specific data,
  118. // as well as checksum computations which verify that the executable has not been modified.
  119. //
  120. // This mechanism cannot be used (in conjunction with CEG_Define_Constant_Function) more then 130 times.
  121. //
  122. // Performance Note:
  123. //
  124. // The full cost of the CEG_ProtectFunction() will be paid on every call of the target function.
  125. // Because this mechanism involves computing checksums of the executable image, this will be more
  126. // expensive then CEG_EncryptFunction(). However, this mechanism is much more likely to cause problems
  127. // for somebody who is attacking the executable with a debugger, as the checksums are likely to find
  128. // the breakpoints being used by the debugger.
  129. //
  130. //----------------------------------------
  131. // CEG_Define_Constant_Function( name, value )
  132. // CEG_Declare_Constant_Function( name )
  133. // CEG_GetConstantValue( name )
  134. //
  135. // These macros create and declare a functions that the game can use to get interesting constants
  136. // for game play. (i.e. Field Of View angle, maximum player velocity etc...)
  137. //
  138. // Computation of CEG_GetConstantValue() involves machine specific information as well as checksums
  139. // of the executing binary (same as CEG_ProtectFunction).
  140. // If the machine is different, or the executable has been modified, then the results returned
  141. // by CEG_GetConstantValue() will be different. The results in the game will depend on how
  142. // the constant is used.
  143. //
  144. // The same Performance Note as for CEG_ProtectFunction() apply to this mechanism.
  145. //
  146. //
  147. // Some General Notes on CEG's macro mechanisms:
  148. //
  149. // The Compiler can eliminate CEG_ProtectFunction() and CEG_EncryptFunction() if it chooses to
  150. // inline your function !!! In general, it's better to use these macros only in function which appear in
  151. // .cpp files (not in inline functions which appear in header files). It's also better if the function
  152. // in which CEG_ProtectFunction() or CEG_EncryptFunction() is placed is not called from within the same file!
  153. //
  154. // C++ Constructors and Destructors :
  155. //
  156. // You can use CEG_ProtectFunction() and CEG_EncryptFunction() within your C++ constructors.
  157. // HOWEVER - if there is a global variable that invokes the constructor, you will be invoking
  158. // the CEG mechanisms before you have executed Steamworks_InitCEGLibrary() - and this will probably crash your game.
  159. //
  160. //
  161. //
  162. #ifndef _CEGCLIENT_H_
  163. #define _CEGCLIENT_H_
  164. #pragma once
  165. //
  166. // Many of the CEG functions implement below compute CRC's over the executing image
  167. // of the game when invoked. This results in their performance impact varying with
  168. // the size of the game executable file.
  169. // A typical result for Steamworks_SelfCheck() and CEG_Protect_Member_Function() is
  170. // 3ms of overhead in a 6MB executable. (Measured in L4D2).
  171. //
  172. // In order to allow more fine grain control of which part of the executable is covered
  173. // by CEG CRC's this macro is provided.
  174. //
  175. // Executable code that is placed in this section WILL NOT have any CRC's covering the code.
  176. // To place code in this section on an entire source file basis use '#pragma code_seg( NO_CEG_SECTION )'
  177. // This places all of the code following the pragma into the NO_CEG_SECTION of the executable.
  178. //
  179. // Care should be taken that the marked code cannot be modified to prevent execution of CEG checks.
  180. // Do not put direct CEG call sites into this section, or most of the call stack leading to a CEG call site.
  181. // This can be used to improve the performance of the Steamwork_SelfCheck() and CEG_Protect_Member_Function() mechanisms
  182. // as they will operate on a smaller portion of the game image.
  183. // Do not overuse, as placing all code into such sections would mean that the hackers could easily
  184. // identify CEG library code - which would be the code not in NO_CEG_SECTION.
  185. //
  186. #define NO_CEG_SECTION ".textnc"
  187. //
  188. // This is the result code the DRM library passes to ExitProcess() when it terminates
  189. // a process that requires DRM processing.
  190. //
  191. #define STEAM_PROCESS_TERMINATE_DRM_REQUIRED 0x8000DEAD
  192. //
  193. // This function should be called exactly once by a client application.
  194. // The Steamworks_InitCEGLibrary() and Steamworks_TermCEGLibrary() will let steam know that a game was
  195. // running no matter what mechanism the user used to start the game.
  196. //
  197. extern bool __cdecl Steamworks_InitCEGLibrary() ;
  198. //
  199. // This function should be called exactly once by a client application -
  200. // A client application should call only one of Steamworks_InitCEGLibrary or Steamworks_MinimumInitCEGLibrary() - NOT BOTH!
  201. //
  202. // This function is provided for those applications incorporating additional DRM mechanisms into their application.
  203. // In those cases it may be appropriate to use Steamworks_MinimumInitCEGLibrary().
  204. // Otherwise, Steamworks_InitCEGLibrary() is the interface that should be used.
  205. //
  206. extern bool __cdecl Steamworks_MinimumInitCEGLibrary();
  207. //
  208. // This function should be called exactly once by a client application, immediately
  209. // before it is going to exit the game.
  210. //
  211. extern bool __cdecl Steamworks_TermCEGLibrary() ;
  212. //
  213. // This function pairs with Steamworks_MinimumInitCEGLibrary().
  214. //
  215. extern bool __cdecl Steamworks_MinimumTermCEGLibrary();
  216. //
  217. // This pair of functions must be called on each thread that uses any CEG mechanism.
  218. // Steamworks_RegisterThread() must be called before any CEG mechanism executes on
  219. // the thread, including all of the CEG_Protect_Member* macros.
  220. // Steamworks_UnRegisterThread() must be called AFTER all CEG mechanisms have been
  221. // executed on a particular thread.
  222. //
  223. // IMPORTANT NOTE REGARDING CEG IN MULTIPLE COMPONENTS -
  224. // This Comment ONLY applies if you are using CEG in multiple DLL's (or a .DLL and .EXE)
  225. // which are loaded in the same process.
  226. // If Steamworks_RegisterThread() is called in DLL A, which invokes DLL B which also
  227. // contains CEG code, then DLL B must call Steamworks_RegisterThread() before any CEG
  228. // function within DLL B is executed, and must call Steamworks_UnRegisterThread() before
  229. // it returns to DLL A.
  230. //
  231. // If a thread executes exclusively in DLL A without calling DLL B, then Steamworks_RegisterThread()
  232. // only needs to be called in DLL A.
  233. //
  234. extern bool __cdecl Steamworks_RegisterThread() ;
  235. extern bool __cdecl Steamworks_UnRegisterThread() ;
  236. //
  237. // This function performs the most basic CEG checks for ownership, and makes no attempt
  238. // to conceal it's inner workings, unlike the remaining API's
  239. //
  240. // If bTerminateIfUnowned is non zero then the CEG will crash the process
  241. // and attempt to return STEAM_PROCESS_TERMINATE_DRM_REQUIRED to the steam client.
  242. // The caller may pass zero (false) to the function, and take responsibility for terminating the game.
  243. // This allows the caller to separate the legitimacy test from the enforcement.
  244. // It is very important that the process have an exit code of STEAM_PROCESS_TERMINATE_DRM_REQUIRED
  245. // if this is done - the Steam Client will use that to report CEG errors to Steam
  246. // and to repair a customer installation. This may arise if the customer
  247. // has upgraded their Operating System, in which case the first time the game
  248. // is launched after the upgrade, CEG may fail to identify the system and cause the game to exit.
  249. // In this situation, the steam client will repair the customer's installation before
  250. // the game is launched again.
  251. //
  252. // The variable argument list to the function is ignored by the steam client,
  253. // but may be used to mask the signature of the function.
  254. //
  255. extern bool __cdecl Steamworks_SimpleCheck( DWORD bTerminateIfUnowned, ... );
  256. //
  257. // This function checks to see whether an application has been 'stolen' - it does
  258. // so by examining properties of the system on which we are running and checking if
  259. // those properties match those expected through the encoding we've done into the binary !
  260. //
  261. // IMPORTANT NOTE : This function has internal metering, it does not always perform its
  262. // full check. The goal is to make it more difficult to discover for hackers to locate
  263. // all of these checks.
  264. //
  265. extern bool __cdecl Steamworks_TestSecret() ;
  266. //
  267. // This function performs the same type of checks as Steamworks_TestSecret(), however
  268. // it has no internal metering - it will always perform a check.
  269. //
  270. extern bool __cdecl Steamworks_TestSecretAlways() ;
  271. //
  272. // This function checks to see whether an application has been 'stolen' - it does
  273. // so by examining the PE file (.dll or .exe) in which the DRM library has been linked
  274. // and determines whether the PE file has been modified.
  275. //
  276. extern bool __cdecl Steamworks_SelfCheck() ;
  277. //
  278. // This function takes an interface pointer returned from a steam dll, and verifies
  279. // that it actually references a legitimate steam client.
  280. //
  281. extern bool __cdecl Steamworks_ValidateComponentInterface(void** lpv) ;
  282. //
  283. // By default - we use WinCrypt API's to do signature validation -
  284. // if somebody desires, they can provide their own implementation.
  285. //
  286. class ISignatureImplementation {
  287. public :
  288. virtual bool
  289. VerifyHash(
  290. //
  291. // First - we specify the data structure which has been 'signed' -
  292. // We sign our signature using Wincrypt's PROV_RSA_FULL provider
  293. // with the CALG_SHA1 algorithm.
  294. //
  295. LPBYTE lpbSignedData,
  296. DWORD cbSignedData,
  297. //
  298. // The signature block is generated using
  299. // CryptCreateHash( RSA FULL PROVIDER, CALG_SHA1 ) and CryptHashData().
  300. // The Hash is then signed using CryptSignHash( Hash(), AT_SIGNATURE, .... )
  301. // generating the specified SignatureBlock !
  302. //
  303. LPBYTE lpbSignatureBlock,
  304. DWORD cbSignatureBlock,
  305. //
  306. // The public key associated with the private key that signed the Hash data !
  307. //
  308. LPBYTE lpbPublicKey,
  309. DWORD cbPublicKey
  310. ) = 0 ;
  311. } ;
  312. //
  313. // This function checks a signature of all the read-only portions of the executing image.
  314. // Unlike other CEG mechanisms, this uses cryptographic mechanisms that are not easily concealed from reverse engineering.
  315. // Additionally, this is a higher cost mechanism as it involves the entire executing image.
  316. // This check can be used at game launch, (before any user interface is displayed) where it will serve as a stalking horse,
  317. // and occasionally throughout execution.
  318. //
  319. // Additionally, neither of Steamworks_ValidateComponentInterface() or Steamworks_SelfValidate() provide multiple implementations.
  320. // Steamworks_TestSecret(), Steamworks_TestSecretAlways(), Steamworks_SelfCheck() will all be multi-plexed across many distinct
  321. // implementations (this is done by mingle.exe). Additional call sites for Steamworks_SelfValidate() are not as valuable as
  322. // additional call sites for the previously mentioned CEG functions.
  323. //
  324. extern bool __cdecl Steamworks_SelfValidate(ISignatureImplementation* pISignatureImplementation) ;
  325. ////////////////////////////////////////////////////
  326. //
  327. // DO NOT CALL THIS FUNCTION !
  328. // This is referenced only through the CEG_Define_Constant_Function
  329. //
  330. typedef DWORD (*PFNSteamworks_ComputeDwordValue)();
  331. extern DWORD __cdecl Steamworks_ComputeDwordValue() ;
  332. //
  333. // DO NOT DO NOT CALL THIS FUNCTION !
  334. //
  335. // This is only referenced indirectly through the CEG_Protect_Virtual_Function macro !
  336. //
  337. extern void* __cdecl Steamworks_ProtectFunction( void*, void* ) ;
  338. //
  339. // DO NOT CALL THIS FUNCTION !
  340. //
  341. // This declaration is used within CEG Concealed function mechanisms to incorporate
  342. // machine specific data into the function concealment mechanism. It's not to be
  343. // directly called.
  344. //
  345. extern void __cdecl Steamworks_GetSecretData( unsigned __int32 /* 32bit unsigned int - all platforms.*/, union _16BYTES_U& );
  346. //
  347. // DO NOT DO NOT CALL THIS FUNCTION !
  348. //
  349. // This function should only be referenced through the CEG_EncryptFunction macro !
  350. //
  351. extern bool __cdecl Steamworks_EncryptedFunctionLoad();
  352. //
  353. // DO NOT DO NOT CALL THIS FUNCTION !
  354. //
  355. // This symbol exists for the benefit of mingle.exe when it processes your .obj files
  356. // and should only appear in the initializers of a CEGProtectedFunction structure !
  357. //
  358. extern void __cdecl Steamworks_InvalidReference() ;
  359. //
  360. // DO NOT CALL THIS FUNCTION - Exists solely for use in macros defined below !
  361. //
  362. // This function exists so we can force optimizing compilers to emit all the CEG
  363. // relevant data, as otherwise the compiler would discard them as unreferenced.
  364. //
  365. extern void __cdecl CEG_ForceReference(const struct CEG_Protection_Thunk&, const char* ) ;
  366. //
  367. // This class is defined purely so we can create derived classes in the CEG_Protect_Member_Function() macro.
  368. // Because that macro must be used within a function, defining a class allows us to generate the necessary
  369. // compiler references to ensure that the compiler does not optimize out CEG functions and symbols.
  370. //
  371. class I_CEG_ForceReference_Interface
  372. {
  373. virtual const CEG_Protection_Thunk* ReferencingFunction(unsigned index) = 0 ;
  374. } ;
  375. ////////////////////////////////////////////////////////////////////////////////
  376. // DO NOT CALL THIS FUNCTION - Exists solely for use in macros defined below !
  377. //
  378. // Together with the I_CEG_ForceReference_Interface allows us to force compilation
  379. // of some of our fancy CEG symbols !
  380. //
  381. extern int __cdecl CEG_ForceReference( class I_CEG_ForceReference_Interface* p ) ;
  382. //
  383. //
  384. ///////////////////////////////////////////////////////////////////////////////
  385. ////////////////////////////////////////////////////////////////////////////////
  386. //
  387. // CEG Internal Macros -
  388. //
  389. // The following are not intended for direct use, but will be instantiated
  390. // by CEG_EncryptFunction()/CEG_ProtectFunction()/CEG_GetConstantValue().
  391. //
  392. //
  393. // These handy macros help to generate unique variable names, as well as messages
  394. // through __pragma( message() ) !
  395. //
  396. #define CEG_UNIQNAME2(x,y) x##y
  397. #define CEG_UNIQNAME1(x,y) CEG_UNIQNAME2(x,y)
  398. #define CEG_UNIQNAME(x) CEG_UNIQNAME1(x,__COUNTER__)
  399. #define CEG_STRING(z) #z
  400. #define CEG_LINE_NUMBER(x) CEG_STRING(x)
  401. #if defined( _M_X64 )
  402. #define CEG_UNIQNAME3(x, y) CEG_STRING( x##y )
  403. #else
  404. #define CEG_UNIQNAME3(x, y) CEG_STRING( _##x##y )
  405. #endif
  406. //
  407. // Too bad there's no hexadecimal 'G', F+1 will do
  408. //
  409. #define CEG_PROTECT_SIGNATURE 0xCEF1CEF1
  410. #define CEG_PROTECT_VIRTUAL_SIGNATURE 0xCEF10000
  411. //
  412. // Define various strings used by CEG as section names through __pragma() directives.
  413. //
  414. #if !defined(CEG_PUBLIC_SECTION_STRINGS)
  415. #define CEG_PUBLIC_SECTION_STRINGS
  416. //
  417. // These macros correspond to section names used by CEG.
  418. //
  419. // The following macros will use C++ pragma's to allocate objects into these
  420. // various sections. No direct reference to these macros should be necessary.
  421. //
  422. #define CEG_META_GRAPH_START ".cegm$ga"
  423. #define CEG_META_GRAPH_END ".cegm$gz"
  424. //
  425. // This section will contain the signature tested by the Steamworks_ValidateSelf() interface
  426. //
  427. #define CEG_SIGNATURE_SECTION ".crsig"
  428. //
  429. // This section will contain the data CEG uses to generate the Constant Function mechanisms !
  430. //
  431. #define CEG_EXTERNAL_VALUE ".cegi$d"
  432. #endif
  433. extern DWORD __cdecl Steamworks_RevealFunction( DWORD_PTR, DWORD_PTR );
  434. extern void __cdecl Steamworks_ForceRef( struct CEG_SwapStruct* );
  435. //
  436. // We use this macro to generate identifiers that Mingle may modify.
  437. // In some .obj manipulations, Mingle will change identifiers in the .obj file -
  438. // And will expect the identifiers to be produced by this macro!
  439. //
  440. // NOTE that the __XXXXXXXX will be turned into digits (essentially a counter)
  441. // by mingle !
  442. //
  443. #define Steamworks_CEG_MingleModifiableName_Prefix Steamworks_CEGIdentifier_
  444. #define Steamworks_CEG_MingleModifiableName_Suffix __XXXXXXXX
  445. #define Steamworks_CEG_MingleModifiableName(name) Steamworks_CEGIdentifier_ ## name ## __XXXXXXXX
  446. #define CEG_TEMPLATE_USE_START_SECTION ".cegtu$a"
  447. #define CEG_TEMPLATE_USE_SECTION ".cegtu$m"
  448. #define CEG_TEMPLATE_USE_END_SECTION ".cegtu$z"
  449. //
  450. // Reserve scratch space for the CEG Implementation to cache results!
  451. //
  452. //
  453. struct Steamworks_ThunkFunction_Scratch
  454. {
  455. DWORD m_rgdw[16] ;
  456. };
  457. //
  458. // Identify the version number of the CEG_SwapStruct structure.
  459. //
  460. #define Steamworks_CEG_SwapVersion 1
  461. //
  462. // This mask specifies that the function specified by CEG_SwapStruct should be prepped by mingle
  463. // to have runtime encryption operations applied to it.
  464. //
  465. #define Steamworks_CEG_EncryptSectionMask 1
  466. //
  467. // This mask specifies that the function specified by CEG_SwapStruct should be marked as COMDAT Select
  468. // Associative to the specification section. The select associative option is only used if
  469. // the original section was already COMDAT Select Any (common for templates and inline functions).
  470. // This flag is used by code within the CEG library implementing various secrets - where we want to
  471. // ensure that the target executable file links the absolute minimum amount of stuff, and does not
  472. // pull in any un-necessary objects.
  473. //
  474. #define Steamworks_CEG_SelectAssocMask 2
  475. //
  476. // This is the macro we use to cause the 'consumption' of a template !
  477. //
  478. #define Steamworks_CEG_InvokeTemplate( arg, flags ) \
  479. static char CEG_SwapName_Local[] = __FUNCDNAME__ ; \
  480. __pragma( section(CEG_TEMPLATE_USE_SECTION, read, write) ) \
  481. static CEG_SwapStruct __declspec(align(1)) __declspec(allocate(CEG_TEMPLATE_USE_SECTION)) \
  482. LocalSwap = { \
  483. Steamworks_CEG_SwapVersion, \
  484. CEG_SwapName_Local, \
  485. Steamworks_CEG_MingleModifiableName( arg ), \
  486. flags, NULL, 0, 0 \
  487. } ; \
  488. Steamworks_ForceRef(&LocalSwap)
  489. #define Steamworks_DeclareCEGTemplate( arg ) \
  490. extern DWORD_PTR __cdecl Steamworks_CEG_MingleModifiableName( arg )( DWORD_PTR )
  491. Steamworks_DeclareCEGTemplate( CacheConcealThunk );
  492. Steamworks_DeclareCEGTemplate( ProtectFunction );
  493. #pragma pack(push, 1)
  494. #if !defined(CEG_LINKOBJECT_DEFINED)
  495. #define CEG_LINKOBJECT_DEFINED
  496. //
  497. // The 'ID' of an object identified by mingle - this
  498. // is large enough to be a GUID or an MD5 computation !
  499. //
  500. struct LinkObjectId
  501. {
  502. BYTE m_rgb[16];
  503. };
  504. #endif
  505. struct CEG_SwapStruct {
  506. //
  507. // Tell Mingle what version of this structure the file was compiled with !
  508. //
  509. DWORD_PTR m_Version;
  510. //
  511. // This field is the decorated name of the function that is being manipulated.
  512. // This is generated through the __FUNCDNAME__ preprocessor directive of Visual Studio.
  513. //
  514. char* m_szDecoratedName;
  515. //
  516. // This points to the function that will 'replace' the specified function.
  517. //
  518. void* m_pfnOriginal;
  519. //
  520. // Reserve space in the structure for communication with mingle.exe and
  521. // cegdll.dll regarding the details of what happens to the swapped code !
  522. //
  523. DWORD_PTR m_SectionOptions;
  524. //
  525. // Based on the Section Options, these fields will be interpreted by Mingle and the CEG runtime.
  526. //
  527. void* m_Reserved1;
  528. DWORD_PTR m_Reserved2;
  529. //
  530. // Mingle will give us the size of the Swap Target function, in bytes !
  531. //
  532. DWORD_PTR m_cbTarget;
  533. //
  534. // This is a mingle generated identifier, that will be used by cegdll.dll and drmpe.exe
  535. // to identify the template used and it's associated metadata !
  536. //
  537. LinkObjectId m_LinkObjectId;
  538. };
  539. //
  540. // This structure must have the exact same size as CEG_SwapStruct, and will be the runtime interpretation
  541. // of the structure ! Mingle will modify relocation records so that the final linked form stores 'distances'
  542. // to the actual referenced items instead of pointers. We do this to reduce relocation records in the final
  543. // target executable, which we believe give data structure feedback to hackers.
  544. //
  545. struct CEG_Runtime_SwapStruct {
  546. //
  547. // This field carries the version of the structure.
  548. //
  549. DWORD_PTR m_Version;
  550. //
  551. // This is the 'distance' to the function that Mingle placed into the .obj file.
  552. // This function is called directly instead of the original 'TargetFunction'
  553. //
  554. // Note that 'distances' are stored by mingle.exe using a relocation type that is appropriate for code.
  555. // That means that distances on both 32 and 64bit platforms are 32 bit signed integers -
  556. // However, this field is 64bits on a 64bit platform. The linker will have stored a 32 bit signed
  557. // integer into the field, so we must do appropriate casting, because we don't have a genuine 64 bit signed integer in here.
  558. // When manipulating the structures, we will at a time turn this field into a full 'pointer like' value
  559. // (i.e. during the CEG process) - so it is convenient for us that it can hold that.
  560. //
  561. INT_PTR m_OffsetSubstitute;
  562. //
  563. // NOTE : All the same comments that apply to m_OffsetSubstitute apply to this field !
  564. //
  565. // This is the distance to the 'Target' function - the function containing the Steamworks_CEG_InvokeTemplate macro
  566. // This TargetFunction may be in an encrypted form, depending on the flags specified in m_SectionOptions!
  567. //
  568. INT_PTR m_OffsetOriginal;
  569. //
  570. // These options specify manipulations that mingle will perform on the 'Original' function
  571. // before it is linked. In particular, it may be turned into a 'Concealed' function - which
  572. // is a self-contained data structure containing the functions op-codes and metadata that can
  573. // be encrypted during the CEG process.
  574. //
  575. DWORD_PTR m_SectionOptions;
  576. //
  577. // We allow the macro to request what Encryption thunk is used in the event that the
  578. // Section Options specify
  579. //
  580. DWORD_PTR m_SectionThunk;
  581. //
  582. // For future use ....
  583. //
  584. DWORD_PTR m_Reserved2;
  585. //
  586. // Mingle will give us the size of the Substitute function, in bytes !
  587. // It is usefull to know the Substitute function size - as during runtime we may
  588. // need to 'search' for it.
  589. //
  590. DWORD_PTR m_cbTarget;
  591. //
  592. // This is a mingle generated identifier, that will be used by cegdll.dll and drmpe.exe
  593. // to identify the template used and it's associated metadata !
  594. //
  595. LinkObjectId m_LinkObjectId;
  596. void* GetOriginalFunction() const
  597. {
  598. return reinterpret_cast<void*>(reinterpret_cast<INT_PTR>(&m_OffsetOriginal)+static_cast<INT32>(m_OffsetOriginal)+sizeof(INT32));
  599. }
  600. void* GetSubstituteFunction() const
  601. {
  602. return reinterpret_cast<void*>(reinterpret_cast<INT_PTR>(&m_OffsetSubstitute)+static_cast<INT32>(m_OffsetSubstitute)+sizeof(INT32));
  603. }
  604. };
  605. #pragma pack(pop)
  606. //
  607. // End of CEG Internal Macros -
  608. //
  609. ////////////////////////////////////////////////////////////////////////////////
  610. //
  611. // The flowing three macros :
  612. // CEG_Define_Constant_Function( name, value ),
  613. // CEG_Declare_Constant_Function( name ),
  614. // CEG_GetConstantValue( name )
  615. //
  616. // Operate together to provide another CEG mechanism for protecting your binary.
  617. //
  618. // Example usage :
  619. //
  620. // header.h :
  621. // /* macro is at File Scope !*/
  622. // CEG_Declare_Constant_Function( ZombiesPerSecond ) ;
  623. //
  624. // main.cpp :
  625. // /* macro is at File Scope !*/
  626. // CEG_Define_Constant_Function( ZombiesPerSecond, 17 ) ;
  627. //
  628. // zombies.cpp :
  629. // /* CEG_GetConstantValue( ZombiesPerSecond ) must be used within a function !*/
  630. //
  631. // void
  632. // ClockTick()
  633. // {
  634. // if( ElapsedTime > 1 ) /* Has 1 second passed ? */
  635. // {
  636. // DWORD cZombies = CEG_GetConstantValue( ZombiesPerSecond ) ;
  637. // for( DWORD i=0; i<cZombies; ++i )
  638. // {
  639. // /* Create a Zombie !*/
  640. // }
  641. // }
  642. // }
  643. //
  644. // Explanation :
  645. //
  646. // CEG_Define_Constant_Fucntion( ZombiesPerSecond, 17 ) defines a function
  647. // that will return 17 (as a DWORD) every time it is called, IF your executable
  648. // has not been tampered with, or copied. This function must NOT be inlined,
  649. // when your game is CEG'd, the code bytes of the function will be modified.
  650. // Putting the Definition in the same file as the usage may allow aggressive compiler
  651. // settings to inline some usages of the function - we recommend that the definition
  652. // never appear with the usage.
  653. //
  654. // CEG_Declare_Constant_Function( ZombiesPerSecond ) generates an extern declaration
  655. // of this function.
  656. //
  657. // CEG_GetConstantValue( ZombiesPerSecond ) calls the function defined by
  658. // CEG_Define_Constant_Function() and declared by CEG_Declare_Constant_Function().
  659. //
  660. // How it Works :
  661. //
  662. // This mechanism is very similar to that provided by CEG_Protect_Member_Function()
  663. // The CEG code will compute checksums over your executing image, and these checksums
  664. // will come to the result specified in the CEG_Declare_Constant_Function() if the
  665. // image has not been tampered with. If a hacker has tampered, this will return a
  666. // random number. By choosing appropriate constants, your game may be rendered
  667. // unplayable, although CEG will not crash the game.
  668. //
  669. // Recommendation :
  670. //
  671. // This CEG functionality degrades the game when the game is tampered with.
  672. // It should be used in conjunction with all the other CEG mechanisms.
  673. // The other CEG mechanisms will immediately crash the game when tampered,
  674. // which makes these mechanisms easy to identify in support calls, online forums etc...
  675. //
  676. // Make sure you include a small number of Steamworks_TestSecretAlways() call
  677. // during the start/load of the game. These will catch Casual Piracy.
  678. // The game degradation caused through this the CEG_Define_Constant_Function() is
  679. // directed at sophisticated pirates, who will have a hard time tracking
  680. // down the results of their modifications of the game image.
  681. //
  682. // IMPORTANT NOTE ABOUT THE VALUE ZERO !
  683. //
  684. // Don't use :
  685. // CEG_Define_Constant_Function( Zero, 0 )
  686. // or :
  687. // CEG_Define_ConstantFloat_Function( FloatZero, 0.0f )
  688. //
  689. // The .obj and .exe parsing mechanisms assume 0 (also known as NULL) is an unbound
  690. // usage - and the resulting calls to CEG_GetConstantValue() will not return 0 (zero)
  691. // (The string 'zero' is fine, of course).
  692. //
  693. //
  694. #define CEG_GetConstantValue( name ) \
  695. CEG_UNIQNAME1( CEG_ConstantValue_, name )()
  696. #define CEG_Declare_ConstantFloat_Function( name ) \
  697. extern float __cdecl CEG_UNIQNAME1( CEG_ConstantValue_, name )()
  698. #define Steamworks_CEG_ValueBind_Signature 0xCEF1DDEE
  699. #define CEG_Define_Constant_Function( name, value ) \
  700. extern "C" { \
  701. __pragma( section(CEG_EXTERNAL_VALUE, read, write) ) \
  702. Steamworks_CEG_ValueBinding __declspec(align(8)) __declspec(allocate(CEG_EXTERNAL_VALUE)) \
  703. CEG_UNIQNAME1( Steamworks_CEG_ValueBinding_, name ) = { \
  704. Steamworks_CEG_ValueBind_Signature, \
  705. 0, \
  706. value, \
  707. reinterpret_cast<DWORD_PTR>( Steamworks_ComputeDwordValue ) , \
  708. } ; \
  709. __pragma( comment( linker, "/INCLUDE:" CEG_UNIQNAME3( Steamworks_CEG_ValueBinding_, name ) ) ) \
  710. }; \
  711. extern DWORD CEG_UNIQNAME1( CEG_ConstantValue_, name )( void ); \
  712. DWORD CEG_UNIQNAME1( CEG_ConstantValue_, name )( void ) \
  713. { \
  714. INT32* pOffset = reinterpret_cast<INT32*>( & CEG_UNIQNAME1( Steamworks_CEG_ValueBinding_, name ).m_ImplementationFunction ) ; \
  715. PFNSteamworks_ComputeDwordValue pfn = reinterpret_cast<PFNSteamworks_ComputeDwordValue>( reinterpret_cast<BYTE*>(pOffset+1) + *pOffset ); \
  716. return (*pfn)(); \
  717. }
  718. #define CEG_Declare_Constant_Function( name ) \
  719. extern DWORD CEG_UNIQNAME1( CEG_ConstantValue_, name )()
  720. //
  721. // These forms of CEG_Define_Constant_Function() appeared in older CEG SDK's, but are no longer available !
  722. //
  723. //
  724. #define CEG_Define_Constant_Function2( name, value ) \
  725. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Defined_Constant_Function2 has been retired and can no longer be used! - use CEG_Define_Constant_Function!") )
  726. #define CEG_Define_ConstantFloat_Function( name, value ) \
  727. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Defined_ConstantFloat_Function has been retired and can no longer be used! - use CEG_Define_Constant_Function!") )
  728. #define CEG_Define_ConstantFloat_Function2( name, value ) \
  729. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Defined_ConstantFloat_Function2 has been retired and can no longer be used! - use CEG_Define_Constant_Function!") )
  730. /***************************************************
  731. ****************************************************
  732. CEG_ProtectFunction and CEG_EncryptFunction
  733. These macros must be placed within the body of a function.
  734. Here is a small example, which describes how CEG_ProtectFunction() operates :
  735. class CMyClass {
  736. virtual void MyVirtualFunction( int SomeArg ) ;
  737. } ;
  738. __declspec(noinline) // This is necessary to prevent compiler optimizations from eliminating CEG check.
  739. void
  740. CMyClass::MyVirtualFunction( int SomeArg ) {
  741. CEG_ProtectFunction();
  742. //
  743. // Now do the real work !
  744. //
  745. }
  746. Void ExampleCall(CMyClass * p )
  747. {
  748. p->MyVirtualFunction( EXAMPLE_CONSTANT ) ; }
  749. }
  750. Now what happens to your binary is the following :
  751. The vtable for CMyClass has been changed to reference a CEG function. When ExampleCall() is executed,
  752. It will actually end up calling CEG code through the vtable. This CEG code preserves the state of the stack
  753. and arguments in a fashion similar to the CRT setjmp() function.
  754. The CEG code will then compute a checksum that incorporates machine identifying information into the checksum.
  755. If nobody has modified the executable (by setting breakpoints, or by changing the executable file) and the executable
  756. is running on the machine it was produced for, then the checksum results in the address of CMyClass::MyVirtualFunction().
  757. In this case, CEG will patch the CONTEXT it got from it's setjmp() operation and longjmp() to CMyClass::MyVirtualFunction().
  758. The setjmp()/longjmp() manipulations allow CEG to do it's work, without having to understand the calling convention
  759. between ExampleCall() and CMyClass::MyVirtualFunction().
  760. Before the CEG code invokes longjmp(), it checks that the address it computed is correct, by computing an MD5 of the
  761. address, and comparing this to a stored MD5. If this comparison fail, CEG terminates the process directly.
  762. You can use CEG_ProtectFunction()/CEG_EncryptFunction() in any kind of function -
  763. C++ member functions, C++ static member functions etc....
  764. *******************************************************
  765. ******************************************************/
  766. #define CEG_ProtectFunction( ) \
  767. Steamworks_CEG_InvokeTemplate( ProtectFunction, 0 )
  768. #define CEG_EncryptFunction( ) \
  769. Steamworks_CEG_InvokeTemplate( CacheConcealThunk, Steamworks_CEG_EncryptSectionMask )
  770. //
  771. // These are previus forms of CEG_ProtectFunction() that appeared in older SDK's - and should be replaced by either CEG_ProtectFunction()
  772. // or CEG_EncryptFunction().
  773. //
  774. #define CEG_Protect_Function(x) \
  775. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Protect_Function has been retired and can no longer be used! - use CEG_ProtectFunction!") )
  776. #define CEG_Protect_StaticMemberFunction(x, y) \
  777. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Protect_StaticMemberFunction has been retired and can no longer be used! - use CEG_ProtectFunction!") )
  778. #define CEG_Protect_Virtual_Function3( name ) \
  779. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Protect_Virtual_Function3 has been retired and can no longer be used! - use CEG_ProtectFunction!") )
  780. #define CEG_Protect_Member_Function( name ) \
  781. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Protect_Member_Function has been retired and can no longer be used! - use CEG_ProtectFunction!") )
  782. #define CEG_Protect_Member_Function2( name ) \
  783. __pragma( message( __FILE__ "(" CEG_LINE_NUMBER(__LINE__) ") : CEG_Protect_Member_Function2 has been retired and can no longer be used! - use CEG_ProtectFunction!") )
  784. //
  785. // This structure is declared to be a platform invariant size !
  786. //
  787. struct Steamworks_CEG_ValueBinding
  788. {
  789. DWORD32 m_Signature;
  790. DWORD32 m_BindingUse;
  791. DWORD64 m_DesiredResult;
  792. DWORD64 m_ImplementationFunction;
  793. };
  794. //////////////////////////////////////////////////////////////
  795. //
  796. // Reference Macros !
  797. //
  798. // These macro's instantiate several CEG data structures as the CEG tools
  799. // (mingle.exe and drmpe.exe) will see them in .obj and .exe files.
  800. //
  801. //
  802. #define CEG_PROTECT_START_SIGNATURE 0xCCEEFF11
  803. #define CEG_PROTECT_END_SIGNATURE 0x11ffeeCC
  804. //
  805. // DO NOT REFERENCE
  806. //
  807. // We specify these symbols here so that the linker will properly
  808. // concatenate the CEG sections together in the final image.
  809. //
  810. // These symbols are only for use by internal code of the CEG library !
  811. //
  812. //
  813. //
  814. //////////////////////////////////////////////////////////////
  815. #endif // _CEGCLIENT_H_