forked from anticitizn/creamlinux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
696 lines (636 loc) · 32 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
#include <cstddef>
#include <iostream>
#include <fstream>
#include "ext/steam/isteamapps.h"
#include "ext/steam/isteamclient.h"
#include "ext/steam/isteamuser.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "ext/ini.h"
#include <string>
#include <cassert>
#include <vector>
#include <map>
#include <unistd.h>
using namespace std;
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
vector<tuple<int, string>> dlcs;
void* (*real_dlsym)(void *handle, const char *name);
mINI::INIStructure ini;
//TODO: move this somewhere else (immediately on lib load?)
//TODO: hook dlvsym as well
void ensure_realdlsym() {
if (real_dlsym == NULL) {
*(void **)(&real_dlsym) = dlvsym(RTLD_NEXT, "dlsym", "GLIBC_2.2.5");
}
}
class Hookey_SteamApps_Class : public ISteamApps {
public:
bool BIsSubscribed() { return true; }
bool BIsLowViolence() { return false; }
bool BIsCybercafe() { return false; }
bool BIsVACBanned() { return false; }
int GetDLCCount() {
spdlog::info("ISteamApps->GetDLCCount called PID {0}", getpid());
auto count = dlcs.size();
auto content = dlcs;
return dlcs.size();
}
bool BIsDlcInstalled(AppId_t appID) {
spdlog::info("ISteamApps->BIsDlcInstalled called");
auto reslt = std::find_if(
std::begin(dlcs),
std::end(dlcs),
[&] (const tuple<int, string> a) { return std::get<0>(a) == appID; }) != std::end(dlcs);
if (reslt) {
spdlog::info("BIsDlcInstalled unlocked {}", appID);
return true;
} else {
return false;
}
}
bool BGetDLCDataByIndex(int iDLC, AppId_t* pAppID, bool* pbAvailable, char* pchName, int cchNameBufferSize) {
spdlog::info("ISteamApps->BGetDLCDataByIndex called");
if ((size_t)iDLC >= dlcs.size()) {
return false;
}
*pAppID = std::get<0>(dlcs[iDLC]);
*pbAvailable = true;
const char* name = std::get<1>(dlcs[iDLC]).c_str();
size_t slen = std::min((size_t)cchNameBufferSize - 1, std::get<1>(dlcs[iDLC]).size());
memcpy((void*)pchName, (void*)name, slen);
*(pchName + slen) = 0x0;
return true;
}
const char* GetCurrentGameLanguage() { return real_steamApps->GetCurrentGameLanguage(); }
const char* GetAvailableGameLanguages() { return real_steamApps->GetAvailableGameLanguages(); }
CSteamID GetAppOwner() { return real_steamApps->GetAppOwner(); }
int GetAppBuildId() { return real_steamApps->GetAppBuildId(); }
void RequestAllProofOfPurchaseKeys() {
spdlog::info("ISteamApps->RequestAllProofOfPurchaseKeys called");
return real_steamApps->RequestAllProofOfPurchaseKeys();
}
bool BIsSubscribedFromFamilySharing() { return real_steamApps->BIsSubscribedFromFamilySharing(); }
bool BIsSubscribedFromFreeWeekend() { return real_steamApps->BIsSubscribedFromFreeWeekend(); }
bool BIsSubscribedApp(AppId_t appID) {
spdlog::info("ISteamApps->BIsSubscribedApp called");
if (ini["methods"]["disable_steamapps_issubscribedapp"] == "true") {
spdlog::info("BIsSubscribedApp function override disabled");
return real_steamApps->BIsSubscribedApp(appID);
} else {
spdlog::info("BIsSubscribedApp creamified called");
auto reslt = std::find_if(
std::begin(dlcs),
std::end(dlcs),
[&] (const tuple<int, string> a) { return std::get<0>(a) == appID; }) != std::end(dlcs);
if (reslt) {
spdlog::info("BIsSubscribedApp unlocked {}", appID);
return true;
} else {
if (ini["config"]["issubscribedapp_on_false_use_real"] == "true") {
return real_steamApps->BIsSubscribedApp(appID);
}
return false;
}
}
}
bool BIsAppInstalled(AppId_t appID) {
spdlog::info("ISteamApps->BIsAppInstalled {0} called", appID);
return real_steamApps->BIsAppInstalled(appID);
}
uint32 GetEarliestPurchaseUnixTime(AppId_t appID) { return real_steamApps->GetEarliestPurchaseUnixTime(appID); }
void InstallDLC(AppId_t appID) { real_steamApps->InstallDLC(appID); }
void UninstallDLC(AppId_t appID) { real_steamApps->UninstallDLC(appID); }
void RequestAppProofOfPurchaseKey(AppId_t appID) { real_steamApps->RequestAppProofOfPurchaseKey(appID); }
bool GetCurrentBetaName(char* pchName, int cchNameBufferSize) { return real_steamApps->GetCurrentBetaName(pchName, cchNameBufferSize); }
bool MarkContentCorrupt(bool bMissingFilesOnly) { return real_steamApps->MarkContentCorrupt(bMissingFilesOnly); }
uint32 GetInstalledDepots(AppId_t appID, DepotId_t* pvecDepots, uint32 cMaxDepots) { return real_steamApps->GetInstalledDepots(appID, pvecDepots, cMaxDepots); }
uint32 GetAppInstallDir(AppId_t appID, char* pchFolder, uint32 cchFolderBufferSize) { return real_steamApps->GetAppInstallDir(appID, pchFolder, cchFolderBufferSize); }
const char* GetLaunchQueryParam(const char* pchKey) { return real_steamApps->GetLaunchQueryParam(pchKey); }
bool GetDlcDownloadProgress(AppId_t nAppID, uint64* punBytesDownloaded, uint64* punBytesTotal) { return real_steamApps->GetDlcDownloadProgress(nAppID, punBytesDownloaded, punBytesTotal); }
SteamAPICall_t GetFileDetails(const char* pszFileName) { return real_steamApps->GetFileDetails(pszFileName); }
int GetLaunchCommandLine(char* pszCommandLine, int cubCommandLine) { return real_steamApps->GetLaunchCommandLine(pszCommandLine, cubCommandLine); }
virtual bool BIsTimedTrial( uint32* punSecondsAllowed, uint32* punSecondsPlayed ) { return real_steamApps->BIsTimedTrial(punSecondsAllowed, punSecondsPlayed); }
ISteamApps* real_steamApps;
};
class Hookey_SteamUser_Class : public ISteamUser {
public:
HSteamUser GetHSteamUser() {
return real_steamUser->GetHSteamUser();
};
bool BLoggedOn() {
return real_steamUser->BLoggedOn();
};
CSteamID GetSteamID() {
return real_steamUser->GetSteamID();
};
int InitiateGameConnection_DEPRECATED( void *pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPortServer, bool bSecure ) {
return real_steamUser->InitiateGameConnection_DEPRECATED(pAuthBlob, cbMaxAuthBlob, steamIDGameServer, unIPServer, usPortServer, bSecure);
};
void TerminateGameConnection_DEPRECATED( uint32 unIPServer, uint16 usPortServer ) {
return real_steamUser->TerminateGameConnection_DEPRECATED(unIPServer, usPortServer);
};
int InitiateGameConnection( void *pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPortServer, bool bSecure ) {
return real_steamUser->InitiateGameConnection_DEPRECATED(pAuthBlob, cbMaxAuthBlob, steamIDGameServer, unIPServer, usPortServer, bSecure);
};
void TerminateGameConnection( uint32 unIPServer, uint16 usPortServer ) {
return real_steamUser->TerminateGameConnection_DEPRECATED(unIPServer, usPortServer);
};
void TrackAppUsageEvent( CGameID gameID, int eAppUsageEvent, const char *pchExtraInfo = "" ) {
return real_steamUser->TrackAppUsageEvent(gameID, eAppUsageEvent, pchExtraInfo);
};
bool GetUserDataFolder( char *pchBuffer, int cubBuffer ) {
return real_steamUser->GetUserDataFolder(pchBuffer, cubBuffer);
};
void StartVoiceRecording( ) {
return real_steamUser->StartVoiceRecording();
};
void StopVoiceRecording( ) {
return real_steamUser->StopVoiceRecording();
};
EVoiceResult GetAvailableVoice( uint32 *pcbCompressed, uint32 *pcbUncompressed_Deprecated, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated) {
return real_steamUser->GetAvailableVoice(pcbCompressed, pcbUncompressed_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated);
};
EVoiceResult GetVoice( bool bWantCompressed, void *pDestBuffer, uint32 cbDestBufferSize, uint32 *nBytesWritten, bool bWantUncompressed_Deprecated, void *pUncompressedDestBuffer_Deprecated, uint32 cbUncompressedDestBufferSize_Deprecated, uint32 *nUncompressBytesWritten_Deprecated, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated ) {
return real_steamUser->GetVoice(bWantCompressed, pDestBuffer, cbDestBufferSize, nBytesWritten, bWantUncompressed_Deprecated, pUncompressedDestBuffer_Deprecated, cbUncompressedDestBufferSize_Deprecated, nUncompressBytesWritten_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated);
};
EVoiceResult DecompressVoice( const void *pCompressed, uint32 cbCompressed, void *pDestBuffer, uint32 cbDestBufferSize, uint32 *nBytesWritten, uint32 nDesiredSampleRate ) {
return real_steamUser->DecompressVoice(pCompressed, cbCompressed, pDestBuffer, cbDestBufferSize, nBytesWritten, nDesiredSampleRate);
};
uint32 GetVoiceOptimalSampleRate() {
return real_steamUser->GetVoiceOptimalSampleRate();
};
HAuthTicket GetAuthSessionTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) {
return real_steamUser->GetAuthSessionTicket(pTicket, cbMaxTicket, pcbTicket);
};
EBeginAuthSessionResult BeginAuthSession( const void *pAuthTicket, int cbAuthTicket, CSteamID steamID ) {
return real_steamUser->BeginAuthSession(pAuthTicket, cbAuthTicket, steamID);
};
void EndAuthSession( CSteamID steamID ) {
return real_steamUser->EndAuthSession(steamID);
};
void CancelAuthTicket( HAuthTicket hAuthTicket ) {
return real_steamUser->CancelAuthTicket(hAuthTicket);
};
EUserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID, AppId_t appID ) {
spdlog::info("ISteamUser->UserHasLicenseForApp {} called", appID);
auto reslt = std::find_if(
std::begin(dlcs),
std::end(dlcs),
[&] (const tuple<int, string> a) { return std::get<0>(a) == appID; }) != std::end(dlcs);
if (reslt) {
spdlog::info("ISteamUser_UserHasLicenseForApp result: owned");
return (EUserHasLicenseForAppResult)0;
} else {
spdlog::info("ISteamUser_UserHasLicenseForApp result: not owned");
return (EUserHasLicenseForAppResult)2;
}
};
bool BIsBehindNAT() {
return real_steamUser->BIsBehindNAT();
};
void AdvertiseGame( CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPortServer ) {
return real_steamUser->AdvertiseGame(steamIDGameServer, unIPServer, usPortServer);
};
SteamAPICall_t RequestEncryptedAppTicket( void *pDataToInclude, int cbDataToInclude ) {
return real_steamUser->RequestEncryptedAppTicket(pDataToInclude, cbDataToInclude);
};
bool GetEncryptedAppTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) {
return real_steamUser->GetEncryptedAppTicket(pTicket, cbMaxTicket, pcbTicket);
};
int GetGameBadgeLevel( int nSeries, bool bFoil ) {
return real_steamUser->GetGameBadgeLevel(nSeries, bFoil);
};
int GetPlayerSteamLevel() {
return real_steamUser->GetPlayerSteamLevel();
};
SteamAPICall_t RequestStoreAuthURL( const char *pchRedirectURL ) {
return real_steamUser->RequestStoreAuthURL(pchRedirectURL);
};
bool BIsPhoneVerified() {
return real_steamUser->BIsPhoneVerified();
};
bool BIsTwoFactorEnabled() {
return real_steamUser->BIsTwoFactorEnabled();
};
bool BIsPhoneIdentifying() {
return real_steamUser->BIsPhoneIdentifying();
};
bool BIsPhoneRequiringVerification() {
return real_steamUser->BIsPhoneRequiringVerification();
};
SteamAPICall_t GetMarketEligibility() {
return real_steamUser->GetMarketEligibility();
};
virtual SteamAPICall_t GetDurationControl() {
return real_steamUser->GetDurationControl();
}
virtual bool BSetDurationControlOnlineState( EDurationControlOnlineState eNewState ) {
return real_steamUser->BSetDurationControlOnlineState(eNewState);
};
ISteamUser* real_steamUser;
};
static std::shared_ptr<Hookey_SteamApps_Class> steamapps_instance;
ISteamApps* Hookey_SteamApps(ISteamApps* real_steamApps) {
if (steamapps_instance != NULL) {
ISteamApps* ptraccess = steamapps_instance.get();
auto debg = ptraccess->GetDLCCount();
return steamapps_instance.get();
} else {
Hookey_SteamApps_Class nhooky;
nhooky.real_steamApps = real_steamApps;
steamapps_instance = std::make_shared<Hookey_SteamApps_Class>(nhooky);
return Hookey_SteamApps(real_steamApps);
}
}
static std::shared_ptr<Hookey_SteamUser_Class> steamuser_instance;
ISteamUser* Hookey_SteamUser(ISteamUser* real_steamUser) {
if (steamuser_instance != NULL) {
return steamuser_instance.get();
} else {
Hookey_SteamUser_Class nhooky;
nhooky.real_steamUser = real_steamUser;
steamuser_instance = std::make_shared<Hookey_SteamUser_Class>(nhooky);
return Hookey_SteamUser(real_steamUser);
}
}
class Hookey_SteamClient_Class : public ISteamClient {
public:
HSteamPipe CreateSteamPipe() {
return real_steamClient->CreateSteamPipe();
}
bool BReleaseSteamPipe( HSteamPipe hSteamPipe ) {
return real_steamClient->BReleaseSteamPipe(hSteamPipe);
}
HSteamUser ConnectToGlobalUser( HSteamPipe hSteamPipe ) {
return real_steamClient->ConnectToGlobalUser(hSteamPipe);
}
HSteamUser CreateLocalUser( HSteamPipe *phSteamPipe, EAccountType eAccountType ) {
return real_steamClient->CreateLocalUser(phSteamPipe, eAccountType);
}
void ReleaseUser( HSteamPipe hSteamPipe, HSteamUser hUser ) {
return real_steamClient->ReleaseUser(hSteamPipe, hUser);
}
ISteamUser *GetISteamUser( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
spdlog::info("ISteamClient->GetISteamUser {0} called (hooked)", pchVersion);
return Hookey_SteamUser(real_steamClient->GetISteamUser(hSteamUser, hSteamPipe, pchVersion));
//return real_steamClient->GetISteamUser(hSteamUser, hSteamPipe, pchVersion);
}
ISteamGameServer *GetISteamGameServer( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamGameServer(hSteamUser, hSteamPipe, pchVersion);
}
void SetLocalIPBinding( const SteamIPAddress_t &unIP, uint16 usPort ) {
return real_steamClient->SetLocalIPBinding(unIP, usPort);
}
ISteamFriends *GetISteamFriends( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamFriends(hSteamUser, hSteamPipe, pchVersion);
}
ISteamUtils *GetISteamUtils( HSteamPipe hSteamPipe, const char *pchVersion ) {
spdlog::info("ISteamClient->GetISteamUtils called");
return real_steamClient->GetISteamUtils(hSteamPipe, pchVersion);
}
ISteamMatchmaking *GetISteamMatchmaking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamMatchmaking(hSteamUser, hSteamPipe, pchVersion);
}
ISteamMatchmakingServers *GetISteamMatchmakingServers( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamMatchmakingServers(hSteamUser, hSteamPipe, pchVersion);
}
void *GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
spdlog::info("ISteamClient->GetISteamGenericInterface {0} called (you're in for a wild ride)", pchVersion);
return real_steamClient->GetISteamGenericInterface(hSteamUser, hSteamPipe, pchVersion);
}
ISteamUserStats *GetISteamUserStats( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamUserStats(hSteamUser, hSteamPipe, pchVersion);
}
ISteamGameServerStats *GetISteamGameServerStats( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamGameServerStats(hSteamUser, hSteamPipe, pchVersion);
}
ISteamApps *GetISteamApps( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
spdlog::info("ISteamClient->GetISteamApps {0} called (hooked)", pchVersion);
return Hookey_SteamApps(real_steamClient->GetISteamApps(hSteamUser, hSteamPipe, pchVersion));
//return real_steamClient->GetISteamApps(hSteamUser, hSteamPipe, pchVersion);
}
ISteamNetworking *GetISteamNetworking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamNetworking(hSteamUser, hSteamPipe, pchVersion);
}
ISteamRemoteStorage *GetISteamRemoteStorage( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamRemoteStorage(hSteamuser, hSteamPipe, pchVersion);
}
ISteamScreenshots *GetISteamScreenshots( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamScreenshots(hSteamuser, hSteamPipe, pchVersion);
}
ISteamGameSearch *GetISteamGameSearch( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamGameSearch(hSteamuser, hSteamPipe, pchVersion);
}
uint32 GetIPCCallCount() {
return real_steamClient->GetIPCCallCount();
}
void SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction ) {
return real_steamClient->SetWarningMessageHook(pFunction);
}
bool BShutdownIfAllPipesClosed() {
return real_steamClient->BShutdownIfAllPipesClosed();
}
ISteamHTTP *GetISteamHTTP( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamHTTP(hSteamuser, hSteamPipe, pchVersion);
}
ISteamController *GetISteamController( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamController(hSteamUser, hSteamPipe, pchVersion);
}
ISteamUGC *GetISteamUGC( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamUGC(hSteamUser, hSteamPipe, pchVersion);
}
ISteamAppList *GetISteamAppList( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
spdlog::info("ISteamClient->GetISteamAppList called");
return real_steamClient->GetISteamAppList(hSteamUser, hSteamPipe, pchVersion);
}
ISteamMusic *GetISteamMusic( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamMusic(hSteamuser, hSteamPipe, pchVersion);
}
ISteamMusicRemote *GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) {
return real_steamClient->GetISteamMusicRemote(hSteamuser, hSteamPipe, pchVersion);
}
ISteamHTMLSurface *GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) {
return real_steamClient->GetISteamHTMLSurface(hSteamuser, hSteamPipe, pchVersion);
}
ISteamInventory *GetISteamInventory( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamInventory(hSteamuser, hSteamPipe, pchVersion);
}
ISteamVideo *GetISteamVideo( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamVideo(hSteamuser, hSteamPipe, pchVersion);
}
ISteamParentalSettings *GetISteamParentalSettings( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamParentalSettings(hSteamuser, hSteamPipe, pchVersion);
}
ISteamInput *GetISteamInput( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamInput(hSteamUser, hSteamPipe, pchVersion);
}
ISteamParties *GetISteamParties( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamParties(hSteamUser, hSteamPipe, pchVersion);
}
ISteamRemotePlay *GetISteamRemotePlay( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->GetISteamRemotePlay(hSteamUser, hSteamPipe, pchVersion);
}
void RunFrame() {
return real_steamClient->RunFrame();
}
void *DEPRECATED_GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) {
return real_steamClient->DEPRECATED_GetISteamUnifiedMessages(hSteamuser, hSteamPipe, pchVersion);
}
void DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess( void (*)() ) {
return real_steamClient->DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess(NULL);
}
void DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess( void (*)() ) {
return real_steamClient->DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess(NULL);
}
void Set_SteamAPI_CCheckCallbackRegisteredInProcess( SteamAPI_CheckCallbackRegistered_t func ) {
return real_steamClient->Set_SteamAPI_CCheckCallbackRegisteredInProcess(func);
}
void DestroyAllInterfaces() {
return real_steamClient->DestroyAllInterfaces();
}
ISteamClient* real_steamClient;
};
static std::shared_ptr<Hookey_SteamClient_Class> steamclient_instance;
ISteamClient* Hookey_SteamClient(ISteamClient* real_steamClient) {
if (steamclient_instance != NULL) {
return steamclient_instance.get();
} else {
Hookey_SteamClient_Class nhooky;
nhooky.real_steamClient = real_steamClient;
steamclient_instance = std::make_shared<Hookey_SteamClient_Class>(nhooky);
return Hookey_SteamClient(real_steamClient);
}
}
#define STEAMAPPS_INTERFACE_VERSION_N008 "STEAMAPPS_INTERFACE_VERSION008"
#define STEAMUSER_INTERFACE_VERSION_020 "SteamUser020"
#define STEAMUSER_INTERFACE_VERSION_021 "SteamUser021"
#define STEAMCLIENT_INTERFACE_VERSION_017 "SteamClient017"
#define STEAMCLIENT_INTERFACE_VERSION_019 "SteamClient019"
extern "C" void* CreateInterface(const char *pName, int *pReturnCode) {
ensure_realdlsym();
void *S_CALLTYPE (*real)(const char *pName, int *pReturnCode);
*(void**)(&real) = real_dlsym(RTLD_NEXT, "CreateInterface");
spdlog::info("CreateInterface called pszVersion: {}", pName);
return real(pName, pReturnCode);
}
extern "C" void Steam_LogOn(HSteamUser hUser, HSteamPipe hSteamPipe, uint64 ulSteamID) {
ensure_realdlsym();
void* S_CALLTYPE (*real)(HSteamUser hUser, HSteamPipe hSteamPipe, uint64 ulSteamID);
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamAPI_LogOn");
spdlog::info("SteamAPI_LogOn called {0} {1} {2}",hUser, hSteamPipe, ulSteamID );
real(hUser, hSteamPipe, ulSteamID);
}
extern "C" bool SteamAPI_ISteamApps_BGetDLCDataByIndex(int iDLC, AppId_t* pAppID, bool* pbAvailable, char* pchName, int cchNameBufferSize) {
spdlog::info("SteamAPI_ISteamApps_BGetDLCDataByIndex called");
if ((size_t)iDLC >= dlcs.size()) {
return false;
}
*pAppID = std::get<0>(dlcs[iDLC]);
*pbAvailable = true;
const char* name = std::get<1>(dlcs[iDLC]).c_str();
size_t slen = std::min((size_t)cchNameBufferSize - 1, std::get<1>(dlcs[iDLC]).size());
memcpy((void*)pchName, (void*)name, slen);
*(pchName + slen) = 0x0;
return true;
}
extern "C" void* S_CALLTYPE SteamInternal_FindOrCreateUserInterface(HSteamUser hSteamUser, const char *pszVersion) {
ensure_realdlsym();
void* S_CALLTYPE (*real)(HSteamUser hSteamUser, const char *pszVersion);
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamInternal_FindOrCreateUserInterface");
spdlog::info("SteamInternal_FindOrCreateUserInterface called pszVersion: {}", pszVersion);
// Steamapps Interface call is hooked here
if (strstr(pszVersion, STEAMAPPS_INTERFACE_VERSION_N008) == pszVersion) {
ISteamApps* val = (ISteamApps*)real(hSteamUser, pszVersion);
spdlog::info("SteamInternal_FindOrCreateUserInterface hooked ISteamApps");
return Hookey_SteamApps(val);
}
// Steamuser interface call is hooked here
if (strstr(pszVersion, STEAMUSER_INTERFACE_VERSION) == pszVersion) {
ISteamUser* val = (ISteamUser*)real(hSteamUser, pszVersion);
spdlog::info("SteamInternal_FindOrCreateUserInterface ISteamUser hook");
return Hookey_SteamUser(val);
}
if (strstr(pszVersion, STEAMUSER_INTERFACE_VERSION_020) == pszVersion) {
ISteamUser* val = (ISteamUser*)real(hSteamUser, pszVersion);
spdlog::info("SteamInternal_FindOrCreateUserInterface ISteamUser(legacy) hook");
return Hookey_SteamUser(val);
}
auto val = real(hSteamUser, pszVersion);
return val;
}
extern "C" void* S_CALLTYPE SteamInternal_CreateInterface(const char *pszVersion) {
ensure_realdlsym();
void* S_CALLTYPE (*real)(const char *pszVersion);
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamInternal_CreateInterface");
spdlog::info("SteamInternal_CreateInterface called pszVersion: {}", pszVersion);
// Steamapps Interface call is hooked here
if (strstr(pszVersion, STEAMAPPS_INTERFACE_VERSION_N008) == pszVersion) {
ISteamApps* val = (ISteamApps*)real(pszVersion);
spdlog::info("SteamInternal_CreateInterface hooked ISteamApps");
return Hookey_SteamApps(val);
}
// Steamuser interface call is hooked here
if (strstr(pszVersion, STEAMUSER_INTERFACE_VERSION) == pszVersion) {
ISteamUser* val = (ISteamUser*)real(pszVersion);
spdlog::info("SteamInternal_CreateInterface ISteamUser hook");
return Hookey_SteamUser(val);
}
if (strstr(pszVersion, STEAMUSER_INTERFACE_VERSION_020) == pszVersion) {
ISteamUser* val = (ISteamUser*)real(pszVersion);
spdlog::info("SteamInternal_CreateInterface ISteamUser(legacy) hook");
return Hookey_SteamUser(val);
}
if (strstr(pszVersion, STEAMCLIENT_INTERFACE_VERSION_017) == pszVersion) {
ISteamClient* val = (ISteamClient*)real(pszVersion);
spdlog::info("SteamInternal_CreateInterface ISteamClient(legacy) hook");
return Hookey_SteamClient(val);
}
if (strstr(pszVersion, STEAMCLIENT_INTERFACE_VERSION_019) == pszVersion) {
ISteamClient* val = (ISteamClient*)real(pszVersion);
spdlog::info("SteamInternal_CreateInterface ISteamClient(legacy) hook");
return Hookey_SteamClient(val);
}
auto val = real(pszVersion);
return val;
}
// for older games
extern "C" ISteamApps *S_CALLTYPE SteamApps() {
ensure_realdlsym();
spdlog::info("SteamApps() called");
//get isteamapps
void* S_CALLTYPE (*real)();
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamApps");
ISteamApps* val = (ISteamApps*)real();
//return val;
return Hookey_SteamApps(val);
}
// for older games
extern "C" ISteamUser *S_CALLTYPE SteamUser() {
ensure_realdlsym();
spdlog::info("SteamUser() called");
//get isteamuser
void* S_CALLTYPE (*real)();
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamUser");
ISteamUser* val = (ISteamUser*)real();
//return val;
return Hookey_SteamUser(val);
}
// disabled for now due to PAYDAY 2 launch issues (Paradox launcher will show 'Not owned' without this)
//TODO: readd when codebase is desphagettifed and can support multiple SDK versions
//TODO: test whether this breaks/fixes other games
// this is a hooking method
// extern "C" ISteamClient *S_CALLTYPE SteamClient() {
// ensure_realdlsym();
// spdlog::info("SteamClient() called");
// //get isteamuser
// void* S_CALLTYPE (*real)();
// *(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamClient");
// ISteamClient* val = (ISteamClient*)real();
// return Hookey_SteamClient(val);
// }
// anti-debugger shenanigans
long ptrace(int request, int pid, void *addr, void *data) {
return 0;
}
static bool hooked = false;
int printdliter(struct dl_phdr_info *info, size_t size, void *data) {
printf("%s\n", info->dlpi_name);
return 0;
}
extern "C" bool SteamAPI_Init()
{
ensure_realdlsym();
std::string creaminipath = "cream_api.ini";
// for developers: enable these 2 lines if you want to log output to a file
// auto logger = std::make_shared<spdlog::sinks::basic_file_sink_mt>("creamlinux_log.txt", true);
// spdlog::default_logger().get()->sinks().push_back(logger);
auto env = std::getenv("CREAM_CONFIG_PATH");
//f env exists, use it
if (env != NULL) {
creaminipath = env;
}
spdlog::info("Reading config from {}", creaminipath);
mINI::INIFile file(creaminipath);
// Open ini file
file.read(ini);
// Find dlc's and add to vector
for (pair<string,string> entry : ini["dlc"]) {
auto dlctuple = std::make_tuple(stoi(entry.first), entry.second);
dlcs.push_back(dlctuple);
spdlog::info("Added dlc with id: {0}, name: {1}", entry.first, entry.second);
}
spdlog::info("SteamAPI_Init called in PID {0}", getpid());
// finish api call
// the spaghetti below this comment is calling the original Init function
// can probably be simplified but i'm no c++ expert
bool (*real)();
*(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamAPI_Init");
char* errstr = dlerror();
if (errstr != NULL) {
spdlog::error("SteamAPI_Init failed; A dynamic linking error occurred: {0}", errstr);
spdlog::error("Listing open libraries.");
dl_iterate_phdr(printdliter, NULL);
return false;
}
spdlog::info("Calling real SteamAPI_Init");
auto retval = real();
spdlog::info("SteamAPI_Init returned {0}", retval);
return retval;
}
struct SContextInitData {
void (*pFn)(void* ctx);
uintptr_t counter;
void *ptr;
};
// uncomment the below line and filelog->info lines to enable dlsym logging for quirky use cases (Proton, mono apps)
// auto filelog = spdlog::basic_logger_mt("dlsym_log", "creamlinux_dlsym_log.txt", true);
//TODO: add a flag to allow users to disable the dlsym hooking method
extern "C" void *dlsym(void *handle, const char *name)
{
// filelog->info("modified dlsym called with {0}", name);
ensure_realdlsym();
/* my target binary is even asking for dlsym() via dlsym()... */
if (!strcmp(name,"dlsym"))
return (void*)dlsym;
if (!strcmp(name, "SteamAPI_Init") && handle != RTLD_NEXT) {
spdlog::info("returning custom impl for {0}", name);
spdlog::info("custom: {0}, real: {1}", (void *)SteamAPI_Init, real_dlsym(RTLD_NEXT, "SteamAPI_Init"));
// filelog->info("returning custom impl for {0}", name);
// filelog->info("custom: {0}, real: {1}", (void *)SteamAPI_Init, real_dlsym(RTLD_NEXT, "SteamAPI_Init"));
return (void *)SteamAPI_Init;
}
if (!strcmp(name, "SteamInternal_CreateInterface") && handle != RTLD_NEXT) {
spdlog::info("returning custom impl for {0}", name);
spdlog::info("custom: {0}, real: {1}", (void *)SteamInternal_CreateInterface, real_dlsym(RTLD_NEXT, "SteamInternal_CreateInterface"));
//filelog->info("returning custom impl for {0}", name);
//filelog->info("custom: {0}, real: {1}", (void *)SteamInternal_CreateInterface, real_dlsym(RTLD_NEXT, "SteamInternal_CreateInterface"));
return (void *)SteamInternal_CreateInterface;
}
// enabling this makes some games (golf with your friends) start calling non-existing functions
//TODO: add a setting to let users use this as a hooking method
// if (!strcmp(name, "CreateInterface") && handle != RTLD_NEXT) {
// filelog->info("returning custom impl for {0}", name);
// filelog->info("custom: {0}, real: {1}", (void *)CreateInterface, real_dlsym(RTLD_NEXT, "CreateInterface"));
// return (void *)CreateInterface;
// }
return real_dlsym(handle,name);
}
//TODO: support this as a hooking method
// extern "C" void* SteamInternal_ContextInit(void *pContextInitData) {
// spdlog::info("SteamInternal_ContextInit called");
// void* S_CALLTYPE (*real)(void *pContextInitData);
// *(void**)(&real) = real_dlsym(RTLD_NEXT, "SteamInternal_ContextInit");
// return real(pContextInitData);
// // struct SContextInitData *contextInitData = (struct SContextInitData *)pContextInitData;
// // if (contextInitData->counter != global_counter) {
// // contextInitData->pFn(&contextInitData->ctx);
// // contextInitData->counter = global_counter;
// // }
// // return &contextInitData->ctx;
// }