diff --git a/SpyCustom/Hooks.hpp b/SpyCustom/Hooks.hpp index 13b95e1..d2dab70 100644 --- a/SpyCustom/Hooks.hpp +++ b/SpyCustom/Hooks.hpp @@ -379,13 +379,11 @@ namespace prediction { inline int* m_pPredictionRandomSeed; }; -void prediction::start(CUserCmd* cmd, C_BasePlayer* localplayer) { - - //printfdbg("prediction run\n"); - +void prediction::start(CUserCmd* cmd, C_BasePlayer* localplayer) +{ if (!m_pPredictionRandomSeed) m_pPredictionRandomSeed = *reinterpret_cast(FindPatternV2("client.dll", "8B 0D ? ? ? ? BA ? ? ? ? E8 ? ? ? ? 83 C4 04") + 2); - *m_pPredictionRandomSeed = cmd->random_seed & 0x7FFFFFFF; + *m_pPredictionRandomSeed = MD5_PseudoRandom(cmd->command_number) & 0x7FFFFFFF; // cmd->random_seed & 0x7FFFFFFF; m_flOldCurtime = iff.g_pGlobals->curtime; m_flOldFrametime = iff.g_pGlobals->frametime; iff.g_pGlobals->curtime = localplayer->GetTickBase() * iff.g_pGlobals->interval_per_tick; @@ -398,10 +396,8 @@ void prediction::start(CUserCmd* cmd, C_BasePlayer* localplayer) { iff.g_pPrediction->FinishMove_v(localplayer, cmd, &m_MoveData); } -void prediction::end(C_BasePlayer* localplayer) { - - //printfdbg("prediction end\n"); - +void prediction::end(C_BasePlayer* localplayer) +{ iff.g_pGameMovement->FinishTrackPredictionErrors(localplayer); iff.g_pMoveHelper->SetHost_v(nullptr); *m_pPredictionRandomSeed = -1; @@ -414,10 +410,8 @@ void fastStop(C_BasePlayer* localplayer, int flags, CUserCmd* cmd) noexcept { if (!localplayer || localplayer->GetLifeState() != LIFE_ALIVE) return; - if (localplayer->GetMoveType() == MOVETYPE_NOCLIP || localplayer->GetMoveType() == MOVETYPE_LADDER || !(flags & FL_ONGROUND) || cmd->buttons & IN_JUMP) return; - if (cmd->buttons & (IN_MOVELEFT | IN_MOVERIGHT | IN_FORWARD | IN_BACK)) return; @@ -432,27 +426,31 @@ void fastStop(C_BasePlayer* localplayer, int flags, CUserCmd* cmd) noexcept const auto negatedDirection = Vector::fromAngle(direction) * -speed; cmd->forwardmove = negatedDirection.x; cmd->sidemove = negatedDirection.y; -} +} bool __stdcall hkCreateMove(float frame_time, CUserCmd* pCmd) { + uintptr_t* frame_pointer; + __asm mov frame_pointer, ebp; + bool& send_packet = *reinterpret_cast(*frame_pointer - 0x1C); + static auto ofunc = ClientModeHook->GetOriginal(24); - + short localid = iff.g_pEngineClient->GetLocalPlayer(); C_BasePlayer* localplayer = static_cast(iff.g_pEntityList->GetClientEntity(localid)); const auto pre_flags = localplayer->GetFlags(); bool interval = !((pCmd->tick_count + 1) % 10); - + if (g_Options.faststop) fastStop(localplayer, pre_flags, pCmd); if (g_Options.slidewalk) pCmd->buttons ^= IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT; if (g_Options.fastduck) pCmd->buttons |= IN_BULLRUSH; - + if (g_Options.bunnyhop && iff.g_pInputSystem->IsButtonDown(KEY_SPACE) && localplayer->GetMoveType() != MOVETYPE_LADDER) if (!(pre_flags & FL_ONGROUND) && pCmd->buttons & (IN_JUMP)) { @@ -465,7 +463,6 @@ bool __stdcall hkCreateMove(float frame_time, CUserCmd* pCmd) pCmd->sidemove = 450.0f; } } - if (*g_Options.c4timer && *(C_GameRulesProxy**)iff.GameRulesProxy) { bool isbombplanted = (*(C_GameRulesProxy**)iff.GameRulesProxy)->IsBombPlanted(); @@ -514,10 +511,9 @@ bool __stdcall hkCreateMove(float frame_time, CUserCmd* pCmd) else if (c4id) c4id = 0; } - if (*g_Options.rankreveal && (pCmd->buttons & IN_SCORE) != 0) { - //credits https://www.unknowncheats.me/forum/counterstrike-global-offensive/331059-rank-reveal-sig-scanning.html + if (*g_Options.rankreveal && (pCmd->buttons & IN_SCORE) != 0) iff.g_pClient->DispatchUserMessage(CS_UM_ServerRankRevealAll, 0, 0, nullptr); - } + if (g_Options.speclist && interval) { @@ -540,28 +536,49 @@ bool __stdcall hkCreateMove(float frame_time, CUserCmd* pCmd) } if (isSomeoneSpectatingYou) ShowMenu(spectatorList); } - - - - /* - if (localplayer) - { - prediction::start(pCmd, localplayer); - if (iff.g_pInputSystem->IsButtonDown(KEY_SPACE) && !(pre_flags & FL_ONGROUND) && (localplayer->GetFlags() & FL_ONGROUND))//predicting that we're gonna hit the ground - { + /* + if (localplayer && g_Options.predict) + { + prediction::start(pCmd, localplayer); + auto post_flags = localplayer->GetFlags(); + if ((post_flags & FL_ONGROUND || post_flags & FL_PARTIALGROUND) && !(pre_flags & FL_ONGROUND || pre_flags & FL_PARTIALGROUND)) //predicting that we're gonna hit the ground + { pCmd->buttons |= IN_DUCK; pCmd->buttons &= IN_JUMP; - } - - prediction::end(localplayer); - } + } + prediction::end(localplayer); + } */ + if (g_Options.blockbot) { + // Get our ground entity. + auto pGroundEntity = iff.g_pEntityList->GetClientEntityFromHandle(localplayer->GetGroundEntity()); + + // Check if there's a player under us. + if (pGroundEntity && _tcsstr(pGroundEntity->GetClientClass()->GetName(), "CCSPlayer")) + { + Vector viewAngles; + iff.g_pEngineClient->GetViewAngles(viewAngles); + Vector localpos = localplayer->GetAbsOrigin(); + Vector entpos = pGroundEntity->GetAbsOrigin(); + Vector delta = localpos - entpos; + float deltaXold = delta[0]; float deltaYold = delta[1]; + delta[0] = deltaXold * cos(viewAngles[1] * PI / 180) + deltaYold * sin(viewAngles[1] * PI / 180); + delta[1] = -deltaXold * sin(viewAngles[1] * PI / 180) + deltaYold * cos(viewAngles[1] * PI / 180); + pCmd->forwardmove = -delta[0] * 40; + pCmd->sidemove = delta[1] * 40; + } + } pCmd->viewangles.Clamp(); + pCmd->forwardmove = std::clamp(pCmd->forwardmove, -450.f, 450.f); + pCmd->sidemove = std::clamp(pCmd->sidemove, -450.f, 450.f); + pCmd->upmove = std::clamp(pCmd->upmove, -320.f, 320.f); - return ofunc(frame_time, pCmd); + //return ofunc(frame_time, pCmd); + + return false; } @@ -658,4 +675,4 @@ int __fastcall hkGetPlayerMoney(void* this_, void* edx, int ent_index) // printfdbg("NotDormant %d Money %d\n", ent_index, ((C_BasePlayer*)player)->GetAccount()); return ((C_BasePlayer*)player)->GetAccount(); } -} +} \ No newline at end of file diff --git a/SpyCustom/Interfaces.cpp b/SpyCustom/Interfaces.cpp index 5aa708f..da20476 100644 --- a/SpyCustom/Interfaces.cpp +++ b/SpyCustom/Interfaces.cpp @@ -278,4 +278,5 @@ void ShowMenu(std::string text) iff.g_pClient->DispatchUserMessage(CS_UM_ShowMenu, 0, textsize + 7, &message); } } - + + \ No newline at end of file diff --git a/SpyCustom/Interfaces.hpp b/SpyCustom/Interfaces.hpp index 781aa71..699a2fd 100644 --- a/SpyCustom/Interfaces.hpp +++ b/SpyCustom/Interfaces.hpp @@ -2,7 +2,7 @@ #define INTERFACES #pragma once -#define DEBUG +//#define DEBUG #ifdef DEBUG #define printfdbg(data, ...) printf(XorStr(data), __VA_ARGS__) @@ -78,9 +78,7 @@ PVOID FindHudElement(const char* name); auto is_code_ptr(void* ptr) -> bool; - -//#include "resource.h" - + class IF { public: IClientEntityList* g_pEntityList = nullptr; @@ -375,5 +373,7 @@ void NETSetConVar(const char* name, const char* value); void TextMsg(std::string text); void ShowMenu(std::string text); std::string GetName(int id); + + #endif diff --git a/SpyCustom/Menu.hpp b/SpyCustom/Menu.hpp index ab01408..bd01484 100644 --- a/SpyCustom/Menu.hpp +++ b/SpyCustom/Menu.hpp @@ -1925,16 +1925,16 @@ long __stdcall hkEndScene(IDirect3DDevice9* pDevice) SetValueUnrestricted("viewmodel_offset_y", g_Options.viewmodel_y); if (ImGui::SliderFloat("Viewmodel pos Z", g_Options.viewmodel_z, -90.0f, 90.0f)) SetValueUnrestricted("viewmodel_offset_z", g_Options.viewmodel_z); - ImGui::SliderFloat("FOV", g_Options.fov, 0, 360); ImGui::NextColumn(); style->ItemSpacing = ImVec2(7.0f, 10.0f); - + + ImGui::Checkbox("Stick to heads", g_Options.blockbot); + DisableElements(*g_Options.bunnyhop, 1); - ImGui::Checkbox("PLACEHOLDER", g_Options.jumpbug); ImGui::Checkbox("Auto strafe", g_Options.autostrafe); DisableElements(*g_Options.bunnyhop, 0); style->ItemSpacing = ImVec2(7.0f, 17.0f); @@ -1942,7 +1942,6 @@ long __stdcall hkEndScene(IDirect3DDevice9* pDevice) ImGui::SliderFloat("Viewmodel ang X", g_Options.viewmodel_ang_x, -180.0f, 180.0f); ImGui::SliderFloat("Viewmodel ang Y", g_Options.viewmodel_ang_y, -180.0f, 180.0f); ImGui::SliderFloat("Viewmodel ang Z", g_Options.viewmodel_ang_z, -180.0f, 180.0f); - /* if (ImGui::SliderFloat("Aspect Ratio", g_Options.aspectratio, 0, 25.0f)) diff --git a/SpyCustom/Options.hpp b/SpyCustom/Options.hpp index 1961277..d50e9aa 100644 --- a/SpyCustom/Options.hpp +++ b/SpyCustom/Options.hpp @@ -644,8 +644,8 @@ public: OPTION(bool, dme_gettextures, false); OPTION(int, dmeloop_count, 0); OPTION(weaponz, weapons, weaponz()); - OPTION(char1024, playername, char1024("ur name")); - OPTION(char1024, playerclan, char1024("ur tag")); + OPTION(char1024, playername, char1024("Your name")); + OPTION(char1024, playerclan, char1024("Your tag")); OPTION(bool, discmsg_active, false); OPTION(char1024, discmsg, char1024("SFUI_QMM_ERROR_VacBanned")); @@ -706,15 +706,13 @@ public: OPTION(bool, faststop, 0); OPTION(bool, moneyreveal, 0); - OPTION(bool, jumpbug, 0); + OPTION(bool, predict, 0); + OPTION(bool, blockbot, 0); }; inline Options g_Options; inline bool g_Unload; - - - - + struct skin { skin(bool active1, int skinid1, int seed1, int stattrak1, bool ownerunk1, float wear1, int quality1, char nametag1[256]) diff --git a/SpyCustom/PatternScan.cpp b/SpyCustom/PatternScan.cpp index c8688ae..9fe1f28 100644 --- a/SpyCustom/PatternScan.cpp +++ b/SpyCustom/PatternScan.cpp @@ -13,7 +13,7 @@ DWORD WaitOnModuleHandle(std::string moduleName) return ModuleHandle; } -DWORD FindPatternV2(std::string moduleName, std::string pattern) +DWORD FindPatternV2_(std::string moduleName, std::string pattern) { const char* pat = pattern.c_str(); DWORD firstMatch = 0; diff --git a/SpyCustom/PatternScan.hpp b/SpyCustom/PatternScan.hpp index 2cbe042..5f0f39f 100644 --- a/SpyCustom/PatternScan.hpp +++ b/SpyCustom/PatternScan.hpp @@ -5,12 +5,15 @@ #include #include #include +#include "XorStr.hpp" #define INRANGE(x,a,b) (x >= a && x <= b) #define getBits( x ) (INRANGE((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xa) : (INRANGE(x,'0','9') ? x - '0' : 0)) #define getByte( x ) (getBits(x[0]) << 4 | getBits(x[1])) +#define FindPatternV2(data1, data2) FindPatternV2_(XorStr(data1), XorStr(data2)) + DWORD WaitOnModuleHandle(std::string moduleName); -DWORD FindPatternV2(std::string moduleName, std::string pattern); +DWORD FindPatternV2_(std::string moduleName, std::string pattern); bool bCompare(const BYTE* Data, const BYTE* Mask, const char* szMask); DWORD FindPattern(std::string moduleName, BYTE* Mask, char* szMask); diff --git a/SpyCustom/Skinchanger.cpp b/SpyCustom/Skinchanger.cpp index a36877e..fa92535 100644 --- a/SpyCustom/Skinchanger.cpp +++ b/SpyCustom/Skinchanger.cpp @@ -371,7 +371,6 @@ bool Changer() if (g_Options.weapons.value->arr[0].active && g_Options.weapons.value->arr[0].modelactive) { - //can cause crash idk why static int lastmdlindex = -1; int curmdlindex = pViewModel->GetModelIndex(); if (lastmdlindex != curmdlindex) @@ -383,6 +382,7 @@ bool Changer() for (int i = 0; i < 20; i++) if (_tcsstr(pViewModel->GetSequenceActivity(i), "draw")) { + printfdbg("SendViewModelMatchingSequence %d to %d (%d)", i, lastmdlindex, defindex); pViewModel->SendViewModelMatchingSequence(i); break; } diff --git a/SpyCustom/SpyCustom.vcxproj b/SpyCustom/SpyCustom.vcxproj index 5156153..fc6e2ce 100644 --- a/SpyCustom/SpyCustom.vcxproj +++ b/SpyCustom/SpyCustom.vcxproj @@ -96,7 +96,7 @@ true true WIN32;NDEBUG;SPYCUSTOM_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true + false NotUsing pch.h stdcpp17 @@ -574,6 +574,7 @@ + diff --git a/SpyCustom/SpyCustom.vcxproj.filters b/SpyCustom/SpyCustom.vcxproj.filters index 6b9f4bb..168e0c7 100644 --- a/SpyCustom/SpyCustom.vcxproj.filters +++ b/SpyCustom/SpyCustom.vcxproj.filters @@ -1358,5 +1358,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/SpyCustom/checksum_md5.cpp b/SpyCustom/checksum_md5.cpp new file mode 100644 index 0000000..9b6099d --- /dev/null +++ b/SpyCustom/checksum_md5.cpp @@ -0,0 +1,263 @@ +#include "sdk/checksum_md5.h" +#include +#include +//#include "tier1/strtools.h" +//#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +//#include "tier0/memdbgon.h" + +// The four core functions - F1 is optimized somewhat +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +// This is the central step in the MD5 algorithm. +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +//----------------------------------------------------------------------------- +// Purpose: The core of the MD5 algorithm, this alters an existing MD5 hash to +// reflect the addition of 16 longwords of new data. MD5Update blocks +// the data and converts bytes into longwords for this routine. +// Input : buf[4] - +// in[16] - +// Output : static void +//----------------------------------------------------------------------------- +static void MD5Transform(unsigned int buf[4], unsigned int const in[16]) +{ + register unsigned int a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +//----------------------------------------------------------------------------- +// Purpose: Start MD5 accumulation. Set bit count to 0 and buffer to mysterious initialization constants. + +// Input : *ctx - +//----------------------------------------------------------------------------- +void MD5Init(MD5Context_t* ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Update context to reflect the concatenation of another buffer full of bytes. +// Input : *ctx - +// *buf - +// len - +//----------------------------------------------------------------------------- +void MD5Update(MD5Context_t* ctx, unsigned char const* buf, unsigned int len) +{ + unsigned int t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((unsigned int)len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) + { + unsigned char* p = (unsigned char*)ctx->in + t; + + t = 64 - t; + if (len < t) + { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +//----------------------------------------------------------------------------- +// Purpose: Final wrapup - pad to 64-byte boundary with the bit pattern +// 1 0* (64-bit count of bits processed, MSB-first) +// Input : digest[MD5_DIGEST_LENGTH] - +// *ctx - +//----------------------------------------------------------------------------- +void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5Context_t* ctx) +{ + unsigned count; + unsigned char* p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + //byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } + else + { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + //byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((unsigned int*)ctx->in)[14] = ctx->bits[0]; + ((unsigned int*)ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (unsigned int*)ctx->in); + //byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, MD5_DIGEST_LENGTH); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *hash - +// hashlen - +// Output : char +//----------------------------------------------------------------------------- +char* MD5_Print(unsigned char* hash, int hashlen) +{ + static char szReturn[64]; + + // Assert(hashlen <= 32); + + // Q_binarytohex(hash, hashlen, szReturn, sizeof(szReturn)); + return szReturn; +} + +//----------------------------------------------------------------------------- +// Purpose: generate pseudo random number from a seed number +// Input : seed number +// Output : pseudo random number +//----------------------------------------------------------------------------- +unsigned int MD5_PseudoRandom(unsigned int nSeed) +{ + MD5Context_t ctx; + unsigned char digest[MD5_DIGEST_LENGTH]; // The MD5 Hash + + memset(&ctx, 0, sizeof(ctx)); + + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char*)&nSeed, sizeof(nSeed)); + MD5Final(digest, &ctx); + + return *(unsigned int*)(digest + 6); // use 4 middle bytes for random value +} \ No newline at end of file