Os Melhores
Conteúdo popular
Mostrando conteúdo com a maior reputação em 26/05/2026 in todas as áreas
-
bacana, na verdade com os emuladores que tem disponivel aqui mesmo na WC isso é tranquilo de fazer... so pegar o cliente seja a versão que quiser e alinhar as structs como a struct_mob struct_score e etc com o cliente... no mais é so editar o serverlist do cliente e logar... é possivel fazer isso com o cliente atual do global tbm se quiser, porem precisa alinhar as structs, com o proprio sniffer que postei ai da pra acertar sizes e etc no global e nos outros clientes so mudar os offsets dos hooks e da pra capturar os packets tbm. o problema maior na verdade é que pra essas versõies ficarem viaveis precisa de um patch no cliente para poder atualizar o size das variaveis, pois sao bem limitadas. no mais a maioria das coisas ja funciona, precisa acertar os calculos de grid de inventario e etc, mas nada muito complicado, ainda mais com as IAs ai, pode extrair as funções BASE_ diretamente do binario do cliente, que ja vai ter a maior parte dos calculos, alinhados com o cliente. por exemplo, segue a BASE_CheckPacketSize do Global int BASE_CheckPacketSize(const unsigned short* pPacket) { if (!pPacket) return 0; struct PacketSizeEntry { unsigned short type; unsigned short expectedSize; }; // Opcode = base_number | flags. Flags: // G2C = 0x0100 (GAME2CLIENT) C2G = 0x0200 (CLIENT2GAME) // DB2G = 0x0400 (DB2GAME) G2DB = 0x0800 (GAME2DB) // DB2NP = 0x1000 NP2DB = 0x2000 // NEW = 0x4000 (custom/extended) // Sizes use Global 12-byte header (no PacketMAC). static const PacketSizeEntry table[] = { // ===================================================== // GAME2CLIENT (0x1xx) — Server → Client // ===================================================== { 0x0101, 140 }, // _MSG_MessagePanel (1|G2C) { 0x0102, 148 }, // _MSG_MessageBoxOk (2|G2C) { 0x0103, 20 }, // 3|G2C — unknown { 0x0104, 184 }, // 4|G2C — unknown { 0x010A, 2808 }, // _MSG_CNFAccountLogin (10|G2C) — SELCHAR+Cargo { 0x0110, 1224 }, // _MSG_CNFNewCharacter (16|G2C) — SELCHAR { 0x0112, 1224 }, // _MSG_CNFDeleteCharacter (18|G2C) — SELCHAR { 0x0114, 2104 }, // _MSG_CNFCharacterLogin (20|G2C) — full MOB+Score { 0x0116, 12 }, // _MSG_CNFCharacterLogout (22|G2C) — STANDARD { 0x0117, 12 }, // _MSG_NewAccountFail (23|G2C) — STANDARD { 0x0119, 12 }, // _MSG_CharacterLoginFail (25|G2C) — STANDARD { 0x011A, 12 }, // _MSG_NewCharacterFail (26|G2C) — STANDARD { 0x011B, 12 }, // _MSG_DeleteCharacterFail (27|G2C) — STANDARD { 0x011C, 12 }, // _MSG_AlreadyPlaying (28|G2C) — STANDARD { 0x011D, 12 }, // _MSG_StillPlaying (29|G2C) — STANDARD { 0x011E, 20 }, // 30|G2C — unknown (STANDARDPARM2?) { 0x0120, 12 }, // 32|G2C — unknown (STANDARD) { 0x0165, 16 }, // _MSG_RemoveMob (101|G2C) — STANDARDPARM { 0x016F, 16 }, // _MSG_DecayItem (111|G2C) — STANDARDPARM { 0x0171, 32 }, // _MSG_CNFGetItem (113|G2C) { 0x0175, 28 }, // _MSG_CNFDropItem (117|G2C) { 0x017C, 344 }, // _MSG_ShopList (124|G2C) — ShopType+Items+Tax { 0x0181, 28 }, // _MSG_SetHpMp (129|G2C) { 0x0182, 28 }, // _MSG_SendItem (130|G2C) { 0x0185, 784 }, // _MSG_UpdateCarry (133|G2C) — Carry[]+Coin { 0x018A, 20 }, // _MSG_SetHpDam (138|G2C) { 0x018B, 16 }, // _MSG_UpdateWeather (139|G2C) — STANDARDPARM { 0x018D, 12 }, // _MSG_ReqChallange (141|G2C) — STANDARD { 0x0193, 16 }, // _MSG_SetClan (147|G2C) — STANDARDPARM { 0x0194, 16 }, // 148|G2C — unknown (STANDARDPARM) { 0x01BF, 36 }, // 191|G2C — unknown { 0x01C1, 24 }, // 193|G2C — unknown (STANDARDPARM3?) // ===================================================== // CLIENT2GAME (0x2xx) — Client → Server // ===================================================== { 0x020C, 124 }, // 12|C2G — unknown { 0x020D, 124 }, // _MSG_AccountLogin (13|C2G) { 0x020E, 292 }, // 14|C2G — unknown (large packet) { 0x020F, 36 }, // _MSG_CreateCharacter (15|C2G) { 0x0211, 48 }, // _MSG_DeleteCharacter (17|C2G) { 0x0213, 36 }, // _MSG_CharacterLogin (19|C2G) { 0x021F, 16 }, // 31|C2G — unknown (STANDARDPARM) { 0x026E, 36 }, // _MSG_CreateItem (110|C2G) { 0x0270, 28 }, // _MSG_GetItem (112|C2G) { 0x0277, 20 }, // _MSG_ApplyBonus (119|C2G) { 0x027B, 16 }, // _MSG_REQShopList (123|C2G) — STANDARDPARM { 0x0289, 12 }, // _MSG_Restart (137|C2G) — STANDARD { 0x028B, 20 }, // _MSG_Quest (139|C2G) — STANDARDPARM2 { 0x028C, 16 }, // _MSG_Deprivate (140|C2G) — STANDARDPARM { 0x028E, 16 }, // _MSG_Challange (142|C2G) — STANDARDPARM { 0x028F, 20 }, // _MSG_ChallangeConfirm (143|C2G) — STANDARDPARM2 { 0x0290, 16 }, // _MSG_ReqTeleport (144|C2G) — STANDARDPARM { 0x0291, 16 }, // _MSG_ChangeCity (145|C2G) — STANDARDPARM { 0x0292, 16 }, // _MSG_SetHpMode (146|C2G) — STANDARDPARM { 0x0295, 160 }, // 149|C2G — unknown { 0x02BC, 140 }, // 188|C2G — unknown { 0x02BD, 24 }, // 189|C2G — unknown (STANDARDPARM3?) { 0x02BE, 20 }, // _MSG_DoJackpotBet (190|C2G) — STANDARDPARM2 { 0x02C2, 24 }, // 194|C2G — unknown (STANDARDPARM3?) { 0x02C3, 132 }, // _MSG_CombineItemLindy (195|C2G) { 0x02C4, 132 }, // _MSG_CombineItemShany (196|C2G) { 0x02C7, 16 }, // 199|C2G — unknown (STANDARDPARM) // ===================================================== // GAME2CLIENT | CLIENT2GAME (0x3xx) — Bidirectional // ===================================================== { 0x0333, 140 }, // _MSG_MessageChat (51|G2C|C2G) { 0x0334, 160 }, // _MSG_MessageWhisper (52|G2C|C2G) { 0x0336, 172 }, // _MSG_UpdateScore (54|G2C|C2G) { 0x0337, 48 }, // _MSG_UpdateEtc (55|G2C|C2G) { 0x0338, 32 }, // _MSG_CNFMobKill (56|G2C|C2G) { 0x0364, 256 }, // _MSG_CreateMob (100|G2C|C2G) { 0x0366, 52 }, // _MSG_Action2 (102|G2C|C2G) { 0x0367, 168 }, // _MSG_Attack (103|G2C|C2G) { 0x0369, 16 }, // _MSG_NoViewMob (105|G2C|C2G) — STANDARDPARM { 0x036A, 20 }, // _MSG_Motion (106|G2C|C2G) { 0x036B, 88 }, // _MSG_UpdateEquip (107|G2C|C2G) { 0x036C, 52 }, // _MSG_Action (108|G2C|C2G) { 0x0373, 36 }, // _MSG_UseItem (115|G2C|C2G) { 0x0374, 20 }, // _MSG_UpdateItem (116|G2C|C2G) { 0x0376, 20 }, // _MSG_SwapItem (118|G2C|C2G) { 0x0378, 32 }, // _MSG_SetShortSkill (120|G2C|C2G) { 0x0379, 24 }, // _MSG_Buy (121|G2C|C2G) { 0x037A, 20 }, // _MSG_Sell (122|G2C|C2G) { 0x037D, 40 }, // _MSG_CNFAddParty (125|G2C|C2G) { 0x037E, 16 }, // _MSG_RemoveParty (126|G2C|C2G) { 0x037F, 44 }, // _MSG_SendReqParty (127|G2C|C2G) { 0x0380, 16 }, // 128|G2C|C2G — unknown (STANDARDPARM) { 0x0383, 216 }, // _MSG_Trade (131|G2C|C2G) { 0x0384, 12 }, // _MSG_QuitTrade (132|G2C|C2G) — STANDARD { 0x0386, 12 }, // _MSG_CNFCheck (134|G2C|C2G) — STANDARD { 0x0387, 16 }, // _MSG_Withdraw (135|G2C|C2G) — STANDARDPARM { 0x0388, 16 }, // _MSG_Deposit (136|G2C|C2G) — STANDARDPARM { 0x0397, 244 }, // _MSG_SendAutoTrade (151|G2C|C2G) { 0x039A, 16 }, // _MSG_ReqTradeList (154|G2C|C2G) — STANDARDPARM { 0x03A6, 132 }, // _MSG_CombineItem (166|G2C|C2G) { 0x03C0, 132 }, // _MSG_CombineItemTiny (192|G2C|C2G) { 0x03C9, 52 }, // _MSG_UseItem2 (201|G2C|C2G) { 0x03CA, 36 }, // 202|G2C|C2G — unknown { 0x03EA, 40 }, // 234|G2C|C2G — unknown // ===================================================== // DB2GAME (0x4xx) — DBSrv → TMSrv // ===================================================== { 0x0401, 140 }, // _MSG_DBMessagePanel (1|DB2G) { 0x0402, 148 }, // _MSG_DBMessageBoxOk (2|DB2G) { 0x0403, 184 }, // 3|DB2G — unknown { 0x0404, 12 }, // 4|DB2G — unknown (STANDARD) { 0x040A, 32 }, // _MSG_DBSavingQuit (10|DB2G) { 0x040B, 12 }, // _MSG_DBCNFAccountLogOut (11|DB2G) — STANDARD { 0x0416, 2808 }, // _MSG_DBCNFAccountLogin (22|DB2G) — SELCHAR+Cargo { 0x0417, 2104 }, // _MSG_DBCNFCharacterLogin (23|DB2G) — full MOB { 0x0418, 1224 }, // _MSG_DBCNFNewCharacter (24|DB2G) — SELCHAR { 0x0419, 1224 }, // _MSG_DBCNFDeleteCharacter (25|DB2G) — SELCHAR { 0x041A, 12 }, // _MSG_DBNewAccountFail (26|DB2G) — STANDARD { 0x041B, 12 }, // 27|DB2G — unknown (STANDARD, gap in TMProject) { 0x041C, 12 }, // _MSG_DBCharacterLoginFail (28|DB2G) — STANDARD { 0x041D, 12 }, // _MSG_DBNewCharacterFail (29|DB2G) — STANDARD { 0x041E, 12 }, // _MSG_DBDeleteCharacterFail (30|DB2G) — STANDARD { 0x041F, 12 }, // _MSG_DBAlreadyPlaying (31|DB2G) — STANDARD { 0x0420, 12 }, // _MSG_DBStillPlaying (32|DB2G) — STANDARD { 0x0421, 12 }, // _MSG_DBAccountLoginFail_Acc (33|DB2G) — STANDARD { 0x0422, 12 }, // _MSG_DBAccountLoginFail_Pas (34|DB2G) — STANDARD { 0x0423, 24 }, // _MSG_DBSetIndex (35|DB2G) — STANDARDPARM3 { 0x0424, 12 }, // _MSG_DBAccountLoginFail_Blk (36|DB2G) — STANDARD { 0x0425, 12 }, // _MSG_DBAccountLoginFail_Dis (37|DB2G) — STANDARD { 0x0439, 20 }, // 57|DB2G — unknown (STANDARDPARM2?) { 0x043B, 12 }, // 59|DB2G — unknown (STANDARD) { 0x043D, 140 }, // 61|DB2G — unknown { 0x043E, 12 }, // 62|DB2G — unknown (STANDARD) // ===================================================== // Multi-flag ranges // ===================================================== { 0x07BE, 180 }, // 190|G2C|C2G|DB2G — unknown { 0x0801, 292 }, // _MSG_DBNewAccount (1|G2DB) — MSG_NewAccount { 0x0802, 36 }, // _MSG_DBCreateCharacter (2|G2DB) { 0x0803, 124 }, // _MSG_DBAccountLogin (3|G2DB) { 0x0804, 36 }, // _MSG_DBCharacterLogin (4|G2DB) { 0x0805, 12 }, // _MSG_DBNoNeedSave (5|G2DB) — STANDARD { 0x0806, 3648 }, // _MSG_SavingQuit (6|G2DB) — full MOB save { 0x0807, 3648 }, // _MSG_DBSaveMob (7|G2DB) — full MOB save { 0x0809, 48 }, // _MSG_DBDeleteCharacter (9|G2DB) { 0x0BBF, 180 }, // 191|G2C|C2G|G2DB — unknown { 0x0E0E, 20 }, // _MSG_War (14|C2G|DB2G|G2DB) — STANDARDPARM2 { 0x0FAA, 52 }, // _MSG_ReqTransper (170|G2C|C2G|DB2G|G2DB) { 0x0FBC, 180 }, // 188|G2C|C2G|DB2G|G2DB — unknown // ===================================================== // NP (DB2NP / NP2DB) ranges // ===================================================== { 0x1001, 48 }, // _MSG_NPReqIDPASS (1|DB2NP) { 0x1004, 12 }, // _MSG_NPNotFound (4|DB2NP) — STANDARD { 0x1005, 10040 }, // _MSG_NPAccountInfo (5|DB2NP) { 0x13BD, 180 }, // 189|G2C|C2G|DB2NP — unknown { 0x2002, 48 }, // _MSG_NPIDPASS (2|NP2DB) { 0x2003, 44 }, // _MSG_NPReqAccount (3|NP2DB) { 0x2006, 10040 }, // _MSG_NPReqSaveAccount (6|NP2DB) — MSG_NPAccountInfo { 0x3007, 28 }, // _MSG_NPDisable (7|DB2NP|NP2DB) { 0x3008, 28 }, // _MSG_NPEnable (8|DB2NP|NP2DB) { 0x300A, 16 }, // _MSG_NPState (10|DB2NP|NP2DB) — STANDARDPARM { 0x3409, 164 }, // _MSG_NPNotice (9|DB2NP|NP2DB|DB2G) { 0x3C0F, 492 }, // 15|DB2NP|NP2DB|DB2G|G2DB — unknown (extended DBSendItem?) }; static const int TABLE_SIZE = sizeof(table) / sizeof(table[0]); unsigned int packetType = pPacket[2]; unsigned short packetSize = pPacket[0]; for (int i = 0; i < TABLE_SIZE; ++i) { if (table[i].type == packetType) { if (packetSize != table[i].expectedSize) { char Buffer[256]{}; // S140 (M2): sprintf_s — buffer 256B é mais que suficiente, // mas modernizado para consistência com resto do código. sprintf_s(Buffer, sizeof(Buffer), "sys, Type check missing type:%u size:%u", packetType, packetSize); // nullsub_11(Buffer, "-sys", 0); // log function stubbed no exe return 1; } return 0; } } return 0; } tem inclusive alguns opcodes novos. nas prints ai por exemplo é a DBSrv que descompilei da DBSRVIN e como da pra ver a TMSRVIN esta conectada nela, a DBSrv esta 100% funcional, com todos os sitemas de importitem updateuser criação de arch/celestial/hardcore tudo funcional, com alguns pequenos bugs corrigidos. E tbm foi reconstruido o NPKO usando todos os packets originais, logando na DBSrv enviando msg ingame global e direcionada, assim como desbilitação da conta para poder editar/analisar, com o implementação extra de desconectar automaticamente a conta quando ela estiver logada e for desabilitada no NPKO, isso nao existia no original.6 pontos
-
🌟 WITH YOUR DESTINY – STAR DESTINY 760 🌟 ⚔️ Reviva a verdadeira nostalgia de 2011 no melhor estilo clássico do WYD! O servidor STAR DESTINY 760 chegou trazendo a experiência raiz que marcou época, com sistemas padrão 2011 e evolução liberada até UC! 🚀 🔥 SERVIDOR SEM LIMITES 🔥 💎 Todos os jogadores já começam com 50.000 DONATE para farmar, evoluir e montar seu personagem do jeito que quiser! ⚡ RECURSOS DO SERVIDOR ✅ Sistema padrão 2011 ✅ Evolução liberada até UC ✅ Área VIP liberada ✅ Área de compras / donate liberada ✅ Loja completa funcionando ✅ Pérgula e Água automáticos padrão ✅ 50.000 Donate inicial para todos ✅ Servidor BETA TEST liberado ✅ Ambiente nostálgico e balanceado ✅ Perfeito para veteranos e novos players 🎮 COMO CRIAR CONTA? É automático! Basta entrar no jogo, digitar seu LOGIN e SENHA e acessar o servidor. 📥 DOWNLOAD DO CLIENTE DOWNLOAD STAR DESTINY 760 💬 GRUPO WHATSAPP OFICIAL WHATSAPP STAR DESTINY 760 🏆 Junte seus amigos, fortaleça seu char e domine o mundo de WYD! 🔥 STAR DESTINY 760 — O clássico de 2011 voltou SEM LIMITES! [Hidden Content] VIRUS TOTAL SCAN [Hidden Content]5 pontos
-
𝗕𝗢𝗔 𝗧𝗔𝗥𝗗𝗘 𝗔 𝗧𝗢𝗗𝗢𝗦, 𝗣𝗘𝗦𝗦𝗢𝗔𝗟! Hoje venho trazer uma contribuição para a área de WYD. Sabemos que muitos launchers antigos já não funcionam tão bem atualmente, além da dificuldade que muita gente tem em encontrar um launcher decente e moderno para seus projetos. Então resolvi liberar esse launcher para a comunidade. Ele foi adaptado para WYD Por mim em cima de uma base de launcher de MU, e acredito que pode ajudar bastante quem está desenvolvendo ou querendo melhorar seu servidor. 𝗢 𝗹𝗮𝘂𝗻𝗰𝗵𝗲𝗿 𝗳𝗼𝗶 𝗱𝗲𝘀𝗲𝗻𝘃𝗼𝗹𝘃𝗶𝗱𝗼 𝗲𝗺 𝗖# 𝗰𝗼𝗺 𝗫𝗔𝗠𝗟. 𝗢 𝗹𝗮𝘂𝗻𝗰𝗵𝗲𝗿 é básico, porém conta com uma interface moderna e algumas APIs avançadas, como: • Sistema de notícias • Download automático do cliente do jogo • Atualização automática de patches • Reparo automático de arquivos corrompidos do Cliente 𝗣𝗔𝗥𝗔 𝗖𝗢𝗠𝗣𝗜𝗟𝗔𝗥 𝗢 𝗟𝗔𝗨𝗡𝗖𝗛𝗘𝗥 𝗡𝗢 𝗩𝗜𝗦𝗨𝗔𝗟 𝗦𝗧𝗨𝗗𝗜𝗢: Basicamente será necessário este ambiente: • Windows + Visual Studio 2026, 2022 ou 2019 Os projetos são Windows Desktop (WPF/WinForms) e utilizam .NET Framework 4.8. 𝗪𝗼𝗿𝗸𝗹𝗼𝗮𝗱 𝗻𝗲𝗰𝗲𝘀𝘀á𝗿𝗶𝗮 𝗻𝗼 𝗩𝗶𝘀𝘂𝗮𝗹 𝗦𝘁𝘂𝗱𝗶𝗼: • “.NET desktop development” (Desenvolvimento para área de trabalho .NET) Essa workload já inclui: • WPF • WinForms • Ferramentas MSBuild 𝗧𝗮𝗺𝗯é𝗺 é 𝗻𝗲𝗰𝗲𝘀𝘀á𝗿𝗶𝗼: • .NET Framework 4.8 Developer Pack (Targeting Pack) Os projetos principais estão em v4.8 / net48, então sem esse pack o projeto não compila corretamente. 𝗡𝘂𝗚𝗲𝘁: • Restore de pacotes NuGet habilitado O Dashboard utiliza o pacote: • System.Text.Json versão 8.0.5 O sistema realiza uma validação básica dos patches através do arquivo version.txt. Caso o arquivo não exista no cliente do usuário, ele será criado automaticamente. A verificação de versão é feita comparando com o arquivo de update hospedado no site. O arquivo Config.json é responsável pela configuração dos textos exibidos no launcher, banners e outras informações visuais. 𝗘𝘂 𝘂𝘁𝗶𝗹𝗶𝘇𝗮𝘃𝗮 𝗻𝗼 𝗺𝗲𝘂 𝗽𝗿𝗼𝗷𝗲𝘁𝗼 𝗱𝗼 𝗥𝗼𝗴𝘂𝗲 𝘂𝗺𝗮 𝗳𝗲𝗿𝗿𝗮𝗺𝗲𝗻𝘁𝗮 𝗱𝗲 𝗰𝗼𝗺𝗽𝗮𝗰𝘁𝗮çã𝗼, 𝗼𝗻𝗱𝗲 𝗮 𝗺𝗲𝘀𝗺𝗮 𝗷á 𝗴𝗲𝗿𝗮𝘃𝗮 𝗼 𝗮𝗿𝗾𝘂𝗶𝘃𝗼 update.json 𝗰𝗼𝗺 𝗮 𝘃𝗲𝗿𝘀ã𝗼 𝗰𝗼𝗿𝗿𝗲𝘁𝗮 𝗱𝗼 𝗽𝗮𝘁𝗰𝗵. A ferramenta utilizada por mim originalmente não será postada, pois os créditos pertencem ao GameCode. Porém é algo relativamente simples de desenvolver até mesmo em c++ para quem deseja criar um compactador nesse mesmo formato de leitura. Ela é bem simples de utilizar: Basta colocar os arquivos/pastas do patch (exemplo: pasta UI), definir a versão do patch — por exemplo, versão 1 — e compactar os arquivos em .zip com os nomes correspondentes das pastas. Exemplo: Env Mesh Effect UI Também é necessário criar o arquivo .json com a versão correspondente do patch, que deve ficar dentro de: Update/versions/ Depois disso, basta substituir o update.json antigo pelo novo gerado pela ferramenta para que a atualização seja reconhecida automaticamente pelo launcher. O launcher faz a leitura dos patches através do update.json nomeados como: version": 1, version": 2, version": 3... E o update.json funciona listando as versões disponíveis dos patches para atualização automática do cliente. 𝗢𝘀 𝗹𝗶𝗻𝗸𝘀 𝗱𝗮𝘀 𝗔𝗣𝗜𝘀 𝗽𝗼𝗱𝗲𝗺 𝘀𝗲𝗿 𝗮𝗹𝘁𝗲𝗿𝗮𝗱𝗼𝘀 𝗻𝗼 𝗮𝗿𝗾𝘂𝗶𝘃𝗼 UpdateConfig.cs. 𝗟𝗲𝗺𝗯𝗿𝗮𝗻𝗱𝗼: As APIs via site cada um deverá desenvolver/adaptar conforme sua necessidade. Não ofereço suporte, estou apenas disponibilizando para quem quiser utilizar, estudar, adaptar ou expandir o projeto. 𝗟𝗜𝗡𝗞 𝗗𝗢 𝗟𝗔𝗨𝗡𝗖𝗛𝗘𝗥: [Hidden Content] scam: [Hidden Content] 𝗟𝗜𝗡𝗞 𝗗𝗔 𝗣𝗔𝗦𝗧𝗔 𝗗𝗘 𝗔𝗣𝗜/𝗨𝗣𝗗𝗔𝗧𝗘: [Hidden Content] 𝗡ã𝗼 𝘃𝗼𝘂 𝗽𝗼𝘀𝘁𝗮𝗿 𝘀𝗰𝗮𝗻 𝗱𝗮 𝗽𝗮𝘀𝘁𝗮 𝗱𝗲 𝗔𝗣𝗜/𝗨𝗽𝗱𝗮𝘁𝗲, 𝗽𝗼𝗶𝘀 𝗮 𝗺𝗲𝘀𝗺𝗮 𝗰𝗼𝗻𝘁é𝗺 𝗮𝗽𝗲𝗻𝗮𝘀 𝗮𝗿𝗾𝘂𝗶𝘃𝗼𝘀 .json 𝗲 𝗻ã𝗼 𝗽𝗼𝘀𝘀𝘂𝗶 𝗻𝗲𝗻𝗵𝘂𝗺 𝘁𝗶𝗽𝗼 𝗱𝗲 𝗲𝘅𝗲𝗰𝘂𝘁á𝘃𝗲𝗹. Espero que seja útil para a comunidade.5 pontos
-
MEUS CANAIS DE VÍDEOS HC CURSOS E TUTORIAIS 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️ VEICARECA GAMES 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️4 pontos
-
Olá! Quem conhece sabe: o produto fala por si, sempre inovando, trazendo funcionalidades novas e sendo constantemente atualizado. *Macro Lan *Filtro de drop com add *Auto agrupar *Auto utilizar *Procurar add com replation *Auto click em npc **Visual Script por nodes ( crie qual quer tipo de macro através de nodes, o céu é o limite ) * Diversas outras funcionabilidades *** Macro Agua para Cons ( auto grupo, notificação por sms ) *** Macro Pesa para Cons (auto grupo, notificação por sms) * Suporte a scripts em lua ( obsoleto, visual script é seu sucessor ) ** Em beta *** serviço extra, preço a parte Em breve vou documentar os nodes e criar os tutorais. Screenshots: Visual Script:3 pontos
-
constexpr auto MSG_PremiumFireWork_Opcode = 0x3CA; struct MSG_PremiumFireWork { PacketHeader Header; int conn; int Motion; char Parm[16]; }; if (Volatile == 19) { MSG_UseItem3* pUseItem = reinterpret_cast<MSG_UseItem3*>(pMsg); MSG_PremiumFireWork stFireWork{}; memset(&stFireWork, 0, sizeof(MSG_PremiumFireWork)); stFireWork.Header.Size = sizeof(MSG_PremiumFireWork); stFireWork.Header.ID = conn; stFireWork.Header.Type = MSG_PremiumFireWork_Opcode; stFireWork.conn = conn; stFireWork.Motion = 100; memcpy(stFireWork.Parm, pUseItem->Parm, sizeof(stFireWork.Parm)); GridMulticast(pMob[conn].TargetX, pMob[conn].TargetY, (MSG_STANDARD*)&stFireWork, 0); if (Amount > 1) BASE_SetItemAmount(Item, Amount - 1); else memset(Item, 0, sizeof(STRUCT_ITEM)); return; }3 pontos
-
100% ATUALIZADO(2026) INTRODUÇÃO A Fox com muito orgulho apresenta seu produto para Grand Chase Classic (Steam/Nexus/Megaxus/Epic Games/etc) Acesse nosso site e tenha acesso à mais produtos exclusivos: Forums - Fox Cheats FUNÇÕES 🎯 Categoria: Mission Hack Auto Kill Delay — Mata todos os mobs da missão automaticamente. Skip Dialog — Pula todos os diálogos possíveis durante a missão. Kill All — Usado junto com o Auto Kill Delay para matar mobs que suportam o sistema. Stealth — Faz com que os mobs não ataquem você. Monster Vac — Agrupa todos os mobs hostis em um único local. Item Vac — Coleta automaticamente todos os itens dropados. Item Hide — Esconde todos os itens da missão para melhor visualização. Auto Boss — Avança automaticamente para a Boss Fight quando disponível. Unlimited Dimensional Time — Permite ficar mais de 15 minutos no portão dimensional. Level Hack [VOID] — Permite jogar o VOID sem precisar ser level 85. Item Spawn — Dropa todos os itens que seriam obtidos na missão. Speed Farm — Carrega uma missão alternativa para acelerar o farm. Damage Mob — Multiplicador de dano que você sofrerá dos mobs. Damage Hack — Aumenta o dano que você causa aos mobs. Auto Portal — Passa as etapas automaticamente sem interação manual. Speed Hack — Acelera a velocidade do jogo. Super Talim Spam — Spama o ataque especial do evento de Talin em qualquer missão. 🏆 Categoria: Mission Result Rank Select — Escolha a pontuação de rank da missão (F até SS). Hits Count — Quantidade de hits que você causou na missão. Combo Count — Número total de combos realizados. Attack Back Count — Número de ataques realizados pelas costas dos inimigos. Hits Takken — Quantidade de hits que você sofreu durante a missão. Damage Count — Total de dano que você causou na missão. 👤 Categoria: Player Stats HP Infinity — Vida infinita para o seu personagem. MP Full — Mana infinita para usar habilidades sem restrição. Hide Nick — Esconde seu nick no jogo [STREAM MODE]. Potion CD — Remove o cooldown para usar poções sem tempo de espera. CoolDown Hack — Remove o cooldown das skills, podendo usar sem limite. Fly Hack — Permite que seu personagem voe livremente. Pet MP — Mana infinita para o seu Pet. Furia Full — Fúria sempre cheia para usar golpes especiais. Item Hack [N] — Permite usar itens do inventário [N] sem possuí-los. Status SS — Aumenta seus atributos para atingir status SS+ e completar eventos/missões especiais. 🤖 Categoria: Bots/Farming Drop Prediction — Permite visualizar os itens que irão dropar dos mobs na missão. Block Dialog — Bloqueia janelas de diálogo para farmar AFK. Anti Kick AFK — Impede o jogo de te expulsar por ficar AFK. Auto Start — Inicia automaticamente as missões. Auto Next Dungeon — Avança automaticamente para a próxima missão. Auto Ready — Confirma "Pronto" automaticamente nas missões. Auto Play Dungeon — Joga automaticamente a missão selecionada. Auto Farm Item — Farma repetidamente o item adicionado na lista. Auto Failed — Faz a missão falhar automaticamente. Auto Farm Cards — Farma cartas automaticamente na missão. 🎮 Categoria: Auto Collect And Quit Collect And Quit — Entra na missão que você desejar, coleta os itens desejado e quita (FARM AUTOMATICO DE ITENS 100% AFK E RAPIDO 🎮 Categoria: AUTO VOID 100% AFK 23 CHAR AUTO VOID 100% AFK 23 CHAR — Entra na missão do void desejada, completa automaticamente com todos os personagens desejados e para (100% AFK) ENTREGA AUTOMÁTICA COMPRE AQUI OU NO SITE: [Hidden Content] SCREEN SHOTS PREÇOS 30 Dias -> R$39,90 ONDE COMPRAR ? Nosso Site -> Forums - Fox Cheats Nosso Discord : [Hidden Content] COMO USAR Abra o cheat Abra o jogo Seja feliz! DOWNLOAD/SCAN DOWNLOAD x64 : [Hidden Content] SCAN x64 : VirusTotal - File - 4851f472de5f1be722f62b62c1da749723ca086eddda36347db9996da39a08502 pontos
-
MEUS CANAIS DE VÍDEOS HC CURSOS E TUTORIAIS 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️ VEICARECA GAMES 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️2 pontos
-
Atualização Importante Prime Video chegou na GlobalHax Depois de muitos testes, ajustes e modificações, temos a felicidade de anunciar que o Prime Video já está disponível em nosso sistema de AutoLogin. No momento, esse recurso ainda está em fase de testes. Por isso, podem ocorrer alguns bugs ou instabilidades. Caso encontre qualquer problema, informe nossa equipe para que possamos corrigir o mais rápido possível. 🎁 Usuários que ajudarem reportando falhas poderão receber dias de brinde como recompensa. Acessar GlobalHax GlobalHax • Plataforma em constante evolução2 pontos
-
📢 Aviso Importante — Comunidade GlobalHax Leia com atenção para não perder acesso, suporte e novidades. Nosso administrador @_saphirel está enfrentando problemas com a conta principal do Discord e já está em contato com o suporte. Como essa conta é dona do servidor oficial, estamos reforçando nossos canais de segurança para garantir que nenhum membro fique sem suporte, novidades ou atualizações. 🛡️ O que estamos fazendo? O site oficial continuará funcionando normalmente. Além disso, ativamos o Fórum Oficial e o Discord Backup como canais de segurança para manter todos os membros conectados. 🎁 Benefício para quem participar Quem entrar no Discord Backup e criar uma conta no Fórum Oficial poderá receber benefícios especiais, conforme disponibilidade. Dias extras na recarga Brindes especiais da administração Prioridade em avisos e atualizações importantes ✅ Como resgatar Após entrar no Discord Backup e criar sua conta no fórum, envie no canal de resgate o seguinte formato: Usuário do fórum: SaphireL Usuário do painel: SaphireL Site Oficial Fórum Oficial Discord Backup Essa é uma medida preventiva para proteger nossa comunidade e manter todos informados.2 pontos
-
Conteúdo da MARTINA OLIVEIRA, conhecida também como BEIÇOLA DO PRIVACY, PRIVACY DELA GRATIS + Videos vazados totalmente pelada, mostrando e fazendo de tudo. Sem frescura e nem anuncios, basta clicar no link e dar play no video, para ver o Privacy gratis é só se cadastrar. PRIVACY OFICIAL GRÁTIS, BASTA SE CADASTRAR [Hidden Content] QUASE 40 VIDEOS VAZADOS [Hidden Content]2 pontos
-
ASSINATURAS ATUALIZADAS Patrocinadora: streamingsbarato.com [Hidden Content] [Hidden Content] [Hidden Content] [Hidden Content] Assinatura será atualizada todos os meses.2 pontos
-
📍LANÇAMENTO DIA 29/05/26 - 18:30H 📍BETA DIA 24/04/26 - 18:30H 🗡VOLTANDO AOS VELHOS TEMPOS🗡 🟢BONIFICAÇÕES PARA QUEM TROUXER GUILDA 📍Links Site/Grupo/Discord: [Hidden Content] [Hidden Content] [Hidden Content] BEST QUALITY SERVER 10.9✅|| GUERRAS ⚔️|| REINOS⚜️ 🔥 TRAGA SUA GUILDA PARA O MELHOR SV# 📜 Sistema de Anuncio de equips e emoji no chat 🎪 Sistema de Loja fantasma 📜 Sistema de Player Info 📜 Sistema de Traja de Montaria 📜 Sistema de Raridade na Montaria 🏹 Sistema de Coliseu 🏹 Sistema de Arena Real Times 🏹 Sistema de RvR refeito 🔍 Sistema de Droplist in game 🎲 Sistema de Conjunto de Item 🎲 Sistema de Skins 🎲 Sistema de Balanceio 🎲 Sistema de AutoMessagem 👑 Otimização do Jogo 👑 Sistema de PvP Balanceado 👑 Diversos outros sistemas de Qualidade ⚜️ Suporte ao jogador excelente ⚜️ Jogabilidade Incrível e única ⚜️ Drop de GOLD Convite Lan entre outras formas ⚜️ Macro Agua & 60 Salas Exclusivas de Agua ⚜️ AntHack & AntDDoS ⚜️ Estabilidade e Otimização do Jogo ⚜️ Eventos dinâmicos ⚜️ Equipe reconhecida por ótimo trabalho de desenvolvimento do jogo na comunidade By: Yokoshen ✅Administrador de Boa procedência ✅Analise de virus(scan) - wyd.exe: [Hidden Content] Apresentação2 pontos
-
🔥 WYD OBSIDIAN – SERVIDOR ATIVO, EVENTOS CONSTANTES E PROGRESSÃO JUSTA! 🔥 Se você procura um servidor econômico, fácil de jogar e com eventos competitivos, o WYD Obsidian é a escolha certa. Aqui a evolução é acessível, a comunidade é ativa e sempre há desafios acontecendo. 🎁 KIT NOVATO – COMEÇE COM VANTAGEM! Todos os novos jogadores recebem benefícios iniciais para facilitar o começo da jornada: 🍗 Frango inicial ⏳ 12 horas de experiência (XP) ✨ 7 dias de Poção Divina Entre no jogo e comece evoluindo desde o primeiro minuto! 👥 KIT MIGRAÇÃO PARA GUILDAS Possui uma guilda e quer começar já competitivo? O Kit Migração está disponível para grupos organizados. 📌 Disponível para guildas com mínimo de 10 jogadores 📌 Suporte especial para adaptação ao servidor 📌 Benefícios exclusivos para início acelerado 📩 Para solicitar o kit migração, entre em contato com a administração. ⚔️ SISTEMAS E CONTEÚDOS DISPONÍVEIS 👹 Sistema de Bosses com recompensa donate 🏟️ Arena Real ativa 🧬 Sistema de Composições 🎯 Servidor econômico e equilibrado 🟢 Fácil de jogar, ideal para novos e veteranos 📅 CRONOGRAMA DE EVENTOS FIXOS 🏰 Guerra de Torre 🕙 Segunda a Sexta – 22:00 🌆 Cidades e Noatun 📅 Domingo – 21:00 e 22:00 🎉 Eventos Exclusivos 📆 Realizados 2 vezes por mês Sempre há atividade acontecendo — prepare sua guilda e participe! 🌟 POR QUE JOGAR NO WYD OBSIDIAN? ✅ Servidor ativo e estável ✅ Progressão rápida e acessível ✅ Eventos frequentes ✅ Ambiente competitivo ✅ Ideal para jogadores solo e guildas ✅ Administração presente e suporte ativo Aqui você evolui, compete e se diverte sem complicação. 🌐 SITE: [Hidden Content] 💬 DISCORD: ([Hidden Content] 🔥 Reúna sua guilda, prepare seus itens e venha dominar o WYD Obsidian! Nos vemos dentro do jogo!2 pontos
-
caso queiram usar troquem pMob_New para pMob e pUser_New para pUser //TMSrv 7.57 00586550 int CreateGuild(int conn, const char* guildName) { //Função Ok int clan = pMob_New[conn].MOB.Clan; if (clan != KINGDOM_BLUE && clan != KINGDOM_RED) { SendClientMessage(conn, FALSE, _NN_Only_InKingdom_B_R); return FALSE; } if (WarDay == GuildDay) { SendClientMessage(conn, FALSE, _NN_NotEquip_Saturday); return FALSE; } if (VsModeState == 1) { SendClientMessage(conn, FALSE, _NN_VS_Server); return FALSE; } if (ServerIndex == -1) { pLog.Error("Buy Guild Item, But, Server Index Undefined", pUser_New[conn].AccountName, pUser_New[conn].IP); return FALSE; } // 00586638 if (GuildCounter == 0) { pLog.Error("Buy Guild Item, But, Guild Counter Zero", pUser_New[conn].AccountName, pUser_New[conn].IP); return FALSE; } // 00586673 if (GuildCounter >= MAX_GUILD) { SendClientMessage(conn, FALSE, _NN_Not_GuildSlotInSrv); pLog.Error("GuildCounter Max.", pUser_New[conn].AccountName, pUser_New[conn].IP); GuildCounter = MAX_GUILD; return FALSE; } // 005866CE int nameLen = strlen(guildName); //Local.3 if (nameLen >= 12 || nameLen <= 0) { SendClientMessage(conn, FALSE, _NN_GSTRING_ERR); return FALSE; } // 00586701 if (pMob_New[conn].Ext2.Quest[9] == 1) { return FALSE; } int inUseName = CheckGuildName(guildName); //Local.6 if (inUseName == TRUE) { SendClientMessage(conn, FALSE, _NN_CANT_USE_ID); return FALSE; } if (pMob_New[conn].MOB.Guild != 0) { return FALSE; } // 00586761 int cost = CreateGuildCost; //Local.9 if ((pMob_New[conn].MOB.Coin - cost) < 0) { SendClientMessage(conn, FALSE, _NN_Not_Enough_Money); return FALSE; } // 00586795 int guildId = (ServerIndex * MAX_GUILD) + GuildCounter; //Local.15 int server = guildId / MAX_GUILD; //Local.18 int guild = guildId & (MAX_GUILD - 1); //Local.21 if (g_pGuildList[server][guild].GuildIndex != 0) { pLog.Error(pLog.Format("Create Guild Samed Index {}-{}-{}", server, guild, guildId), pUser_New[conn].AccountName, pUser_New[conn].IP); GuildCounter++; return FALSE; } // 0058683C pMob_New[conn].MOB.Guild = guildId; pMob_New[conn].MOB.GuildLevel = 9; // Líder pMob_New[conn].GetCurrentScore(conn); GuildCounter++; pMob_New[conn].MOB.Coin -= cost; SendUpdateCoin(conn); SendClientMessage(conn, FALSE, _SN_CREATEGUILD, pLog.Format("{}", guildName)); // 005868D1 MSG_CreateMob pCreateMob{}; GetCreateMob(conn, &pCreateMob); GridMulticast(pMob_New[conn].TargetX, pMob_New[conn].TargetY, (MSG_STANDARD*)&pCreateMob, FALSE); SaveUser(conn, 0); pLog.System(pLog.Format("Create Guild Medal {}({}), Idx:{} Count:{}", pMob_New[conn].MOB.MobName, guildName, guildId, GuildCounter), pUser_New[conn].AccountName, pUser_New[conn].IP); MSG_CreateGuild pCreateGuild{}; pCreateGuild.Header.Type = _MSG_CreateGuild; pCreateGuild.Header.ID = conn; pCreateGuild.Header.Size = sizeof(MSG_CreateGuild); pCreateGuild.GuildId = guildId; strncpy_s(pCreateGuild.GuildName, 12, guildName, 12); pCreateGuild.Citizen = GetCitizen(conn); DBServerSocket.SendOneMessage((char*)&pCreateGuild, pCreateGuild.Header.Size); return TRUE; }2 pontos
-
⚔️WYD INFINITY ⚔️ 📅 Inaugurado dia: 01/05/2026 às 13h 📌 Informações Gerais Versão: 7.89 Dificuldade: Easy / Medium UP Rápido: Mortal/Arch UP Celestial: Easy até 120/UP 120 - 120+ Medium Contas por IP: (5) 🔥 "O Farm te prepara. O PVP te define." 📌 Sistemas Guerras de Guilds Arena Real Pesadelo celestial liberado Dominação de Bosses com espólios valiosos Droplist com filtro de drop Sistema de Honra Valioso e Diferenciado Sistema Guerra entre Reinos Player Info Ranking atualizado Sistema de Balanceamento PVP e PVE Baú de carga com 4 slots Resoluções Widescreen sem distorções Loja desvinculada: Progrida livremente Loja de Donate: Acesse de qualquer lugar Novidades de NPCs: recicladores e compositores Novos slots: colar, cinto, traje montaria Sistema Revigorante (proteção de montaria) Fada Dourada: agrupador de itens, filtro e macro de água Auto Grupo Anti-Hack · Anti-DDoS Servidor Estável 24/7 Entre outros... 🌐Redes Sociais 🌍 Site: [Hidden Content] 💬 Discord: [Hidden Content] 📸 Instagram: [Hidden Content] 📱 WhatsApp: [Hidden Content] 🌐Download: Download do Cliente : DOWNLOAD DO CLIENT Scan CLIENT Scan EXE Administrador por: G2K 📌 Imagens sobre o WYD INFINITY Campo iniciante de ARMIA: Sistemas: Painéis no servidor: NPC'S (Se compra em gold e itens)(Ambos são FARM) VALE ESCONDIDO (CONTÉM 3 ANDARES) CAPAS CELESTIAIS1 ponto
-
1 ponto
-
🚀 Confira as funções incríveis completamente gratuitas disponíveis no nosso hack! Com foco em performance, praticidade e diversão, você vai turbinar sua experiência como nunca antes! 🔥 🔹 Zerar Tempo de Recarga – Use suas skills o quanto quiser, sem esperar! 🔹 HP Cheio – Mantenha sua vida sempre no máximo. 🔹 MP Cheio – Nunca mais fique sem mana! 🔹 Bloquear Popup – Diga adeus àquelas telas chatas que aparecem no jogo. 🔹 Imã de Itens – Os itens virão direto até você! 🔹 Anti-AFK – Permaneça na sala mesmo se precisar se ausentar por um tempo. 🔹 Pula Diálogos – Corte direto para a ação, sem enrolação . 🔹 Rank SS – Substitui a pontuação da tela para garantir classificação SS. 🔹 Modo Streamer – Oculta textos e detalhes visuais do jogo. 🔹Imã de Monstros – Atrai todos os monstros até o jogador. 🆓 Atenção! Algumas das funcionalidades listadas estão disponíveis gratuitamente por tempo limitado. No futuro, as funções free poderão ser reduzidas, conforme o desenvolvimento do projeto. 📸 Screenshots: 🔧 Como usar: É simples e rápido começar a usar: 1- Baixe o cliente. 2- Abra o programa e clique em “Injetar”. 3- Inicie o Grand Chase normalmente. 4- Pressione [Insert] para exibir ou ocultar o menu. 5- Aproveite todos os recursos e domine o jogo! ⚠️ Aviso: Ao executar o cliente, sempre clique com o botão direito e selecione “Executar como administrador” para evitar problemas de permissão. Certifique-se também de que o Grand Chase não esteja em modo tela cheia, pois isso pode causar falhas durante a injeção. Se você utiliza Steam: Feche completamente a execução da steam e após isso execute a mesma como administrador, também de preferência a execução do Grandchase via atalho ao invés da execução direta na biblioteca da Steam. [Hidden Content] Erro ao injetar no GrandChase? Em alguns casos, é necessário desabilitar o Windows Defender, a proteção em tempo real e o antivírus instalado no sistema. Mesmo que nosso software não seja malicioso, os antivírus podem identificá-lo como uma ameaça falsamente (falso positivo), pois ele realiza operações avançadas de injeção na memória de outro processo — algo comum em cheats ou ferramentas legítimas de modificação de jogos. Isso faz com que algumas proteções bloqueiem o funcionamento correto do injetor ou até excluam arquivos essenciais automaticamente. Garantimos que o produto é seguro e limpo. Desativar temporariamente a proteção permite que a injeção ocorra corretamente. 🗓️ Hack Atualizado em: 17/06/20261 ponto
-
/* Estilos CSS contidos para o tópico */ .gh-topic-container { font-family: 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif; background-color: #0b0b0b; /* Fundo super escuro para o tópico */ color: #e0e0e0; padding: 30px; border-radius: 10px; max-width: 850px; margin: 20px auto; box-shadow: 0 0 40px rgba(0, 0, 0, 0.8); border: 1px solid #222; } /* ---- Estilos do Banner ---- */ .gh-banner-wrapper { width: 100%; margin-bottom: 35px; border-radius: 12px; overflow: hidden; box-shadow: 0 15px 35px rgba(229, 9, 20, 0.3); /* Glow vermelho forte no banner */ border-bottom: 3px solid #E50914; } .gh-banner-img { width: 100%; height: auto; display: block; transition: transform 0.5s ease; } .gh-banner-wrapper:hover .gh-banner-img { transform: scale(1.02); /* Efeito sutil de zoom ao passar o mouse */ } /* ---- Tipografia e Conteúdo ---- */ .gh-main-title { font-size: 2.8rem; font-weight: 900; text-transform: uppercase; margin-bottom: 10px; text-align: center; letter-spacing: -1px; color: #ffffff; } .gh-highlight-red { color: #E50914; text-shadow: 0 0 15px rgba(229, 9, 20, 0.6); } .gh-subtitle-topic { font-size: 1.3rem; color: #aaaaaa; text-align: center; margin-bottom: 40px; font-weight: 300; border-bottom: 1px solid #333; padding-bottom: 20px; } /* Caixa de Destaque da Bypass */ .gh-feature-box { background: linear-gradient(145deg, #1a1a1a, #111111); border-left: 5px solid #E50914; padding: 25px; border-radius: 8px; margin-bottom: 40px; } .gh-feature-title { font-size: 1.5rem; color: #E50914; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; } .gh-feature-title::before { content: '⚡'; margin-right: 10px; } .gh-text-content { font-size: 1.1rem; line-height: 1.7; color: #d1d1d1; margin-bottom: 20px; } /* Lista de melhorias */ .gh-list { list-style: none; padding: 0; margin: 30px 0; display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; } .gh-list li { background: rgba(229, 9, 20, 0.1); border: 1px solid #E50914; color: #fff; padding: 10px 20px; border-radius: 50px; font-weight: 600; font-size: 0.9rem; box-shadow: 0 0 10px rgba(229, 9, 20, 0.2); } /* ---- Botão ---- */ .gh-button-container { text-align: center; margin-top: 50px; margin-bottom: 30px; } .gh-cta-button { background: linear-gradient(to right, #E50914, #B20610); color: white !important; padding: 18px 50px; text-decoration: none; font-size: 1.2rem; font-weight: 800; border-radius: 6px; transition: all 0.3s ease; display: inline-block; text-transform: uppercase; border: none; cursor: pointer; box-shadow: 0 10px 30px rgba(229, 9, 20, 0.5); position: relative; overflow: hidden; } .gh-cta-button:hover { transform: translateY(-3px); box-shadow: 0 15px 40px rgba(229, 9, 20, 0.7); } .gh-footer-topic { text-align: center; font-size: 0.8rem; color: #666; margin-top: 40px; } /* ---- Estilos da seção VirusTotal ---- */ .gh-virustotal-box { background: #1a1a1a; border: 1px solid #E50914; border-left: 5px solid #E50914; padding: 25px; margin: 30px 0; border-radius: 8px; } .gh-virustotal-title { font-size: 1.5rem; color: #E50914; font-weight: bold; margin-bottom: 15px; } .gh-vt-link { color: #ff6b6b; text-decoration: underline; word-break: break-all; font-weight: bold; } .gh-vt-link:hover { color: #fff; text-shadow: 0 0 10px rgba(229, 9, 20, 0.8); } .gh-vt-note { margin-top: 15px; background: rgba(229, 9, 20, 0.1); padding: 15px; border-radius: 5px; font-size: 1rem; color: #ccc; } O Retorno do Auto Login GlobalHax Mais rápido. Mais seguro. Indetectável. Após um período estratégico de desenvolvimento, a equipe GlobalHax tem o orgulho de anunciar o retorno da nossa ferramenta mais popular para Netflix. Não apenas corrigimos os problemas anteriores; nós redefinimos o funcionamento. Bypass Reestruturada por Completo Jogamos o código antigo fora. O novo sistema de Auto Login utiliza um método de injeção de tokens completamente novo, desenhado para contornar as mais recentes atualizações de segurança da plataforma de streaming. Isso significa maior estabilidade e um risco de queda drasticamente reduzido. 🔍 Análise de Segurança - VirusTotal Link da verificação: [Hidden Content] ⚠️ As detecções apontadas são de vírus genérico, decorrentes da ofuscação utilizada para proteger o código fonte do software. Nenhum comportamento prejudicial ao computador está presente. Este é um falso positivo comum em ferramentas de bypass que utilizam técnicas de proteção de propriedade intelectual. ✅ Status: ONLINE 🛡️ Bypass v3.0 (Nova) ⚡ Injeção Instantânea 🔒 Segurança Reforçada ACESSAR DOWNLOAD AGORA GlobalHax Development Team © 2026. Use com responsabilidade.1 ponto
-
ACREDITAM QUE O BRASIL VAI GANHAR O HEXA EM 2026? A Seleção Brasileira chega para a Copa de 2026 com uma geração que divide opiniões. A convocação mistura experiência e juventude, com nomes como Neymar, Vinícius Júnior, Raphinha, Casemiro, Marquinhos e Endrick. Enquanto alguns torcedores acreditam que o ataque pode ser um dos melhores do mundo, outros questionam algumas escolhas da convocação e a força defensiva da equipe. O Brasil carrega uma história gigantesca em Copas do Mundo, marcada por lendas como Pelé, Romário, Ronaldo Fenômeno, Ronaldinho Gaúcho, Rivaldo e Cafu, jogadores que ajudaram a conquistar os cinco títulos mundiais da Seleção. Na opinião de vocês, essa geração atual tem futebol para conquistar o tão sonhado hexa? Neymar ainda consegue decidir? Vinícius Júnior pode ser o principal nome da Copa? E quem ficou de fora da convocação que merecia uma chance? Qual seria sua convocação ideal ? Debate aberto para opiniões. Me : Mudaria completamente kkkkk MEU 10 E FAIXA ! KKKKKKKK (sem clubismo)1 ponto
-
Sem muitas delongas, segue o repositório abaixo do cliente do wyd descompilado. [hide][Hidden Content]] Este projeto é uma descompilação e o mesmo pode e contém problemas. Sinta-se a vontade para reportá-los e abrir um pull request para o projeto (esperamos que você faça isso). Autores: Eric Santos (SKEWED) Wed Souza (FREEDOM) Kevin Kouketsu (shepher)1 ponto
-
📌 [LANÇAMENTO] FoxMap Studio V1 — Open Source O editor de mapas mais completo para WYD Fala galera da WebCheats! Se você administra ou está desenvolvendo um servidor de With Your Destiny, sabe o quão trabalhoso e limitado costuma ser o processo de criação e edição de mapas usando ferramentas antigas. Pensando nisso, foi desenvolvido o FoxMap Studio V1, uma ferramenta revolucionária que vai mudar completamente a forma como você customiza o seu servidor! Assista ao vídeo demonstrativo completo e veja a ferramenta em ação: 👉 [Hidden Content] 🔥 O que faz o FoxMap Studio ser diferente? O FoxMap Studio foi criado do zero para ser intuitivo, rápido e extremamente poderoso. Chega de sofrer com ferramentas travadas que exigem reinicializações constantes ou processos manuais complexos. [Hidden Content] [Hidden Content] [/hide] 🌟 Principais Recursos: Edição Visual Completa: Interface limpa, moderna e totalmente interativa para você focar no que realmente importa: a criatividade do seu mapa. Modificações em Tempo Real: Veja cada alteração de terreno, texturas e objetos acontecer instantaneamente na sua tela. Editor Avançado de Terrenos e Alturas: Suba montanhas, crie vales e ajuste o relevo do mapa com pincéis dinâmicos e precisos. Pintura Dinâmica de Texturas: Aplique e misture diferentes texturas de solo diretamente no mapa de forma suave e rápida. Importação e Posicionamento de Objetos 3D: Adicione construções, decorações, portais e elementos de cenário de maneira extremamente simples (com suporte a arquivos .glb/.gltf e conversão inteligente para o formato do cliente). Gestão de Atributos do Mapa: Configure zonas de PvP, áreas seguras (No-PvP), zonas de drop ou teleportes diretamente pela interface do estúdio. Integração Direta com o Cliente: Teste e salve suas alterações diretamente nos arquivos do jogo de forma prática. 📺 Veja o Passo a Passo no Vídeo! No vídeo oficial, mostramos desde a interface de login da plataforma WYD Fox Studio até a criação prática de um cenário completo: Como abrir e carregar os mapas existentes do seu cliente. Utilização das ferramentas de pintura de terreno e elevação de mesh. Importação e rotação livre de objetos e decorações 3D no cenário. Aplicação de efeitos climáticos e iluminação personalizada no mapa. Conversão e salvamento automático dos arquivos para rodar perfeitamente no jogo. Assista aqui: Como Criar Mapas Customizados para WYD — FoxMap Studio 🚀 Como ter acesso? [Hidden Content] A ferramenta conta com uma versão de testes gratuita para você conhecer o potencial do editor. Desenvolvedor: Foxdemo / WYD Fox Studio Para suporte, atualizações constantes e mais ferramentas da nossa suíte de desenvolvimento (Editores de Itens, NPCs, Monstros e Quests em breve!), entre no nosso Discord oficial (link disponível na descrição do vídeo do YouTube). Deixe seu comentário abaixo dizendo o que achou da ferramenta ou qual recurso você gostaria de ver nas próximas atualizações!1 ponto
-
1 ponto
-
MEUS CANAIS DE VÍDEOS HC CURSOS E TUTORIAIS 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️ VEICARECA GAMES 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️1 ponto
-
Fala pessoal blz, estou descompilando o sistema de painéis do WYD Global e pra facilitar minha vida criei esse script .idc que faz a analise completa e extrai diversas informações digamos interessantes do cliente, o que facilita bem a vida. Como fiz para o WYD trabalha só com o exes compilados em MSVC, mas pode facilmente ser ajustado para trabalhar com outros compiladores e tbm outros exes. No próprio script tem a descrição das opções de configuração. Para usarem, salvem como XXXXX.idc, basta carregar o exe no IDA Shift+F2 importar o script ou colar o conteúdo no editor de script e rodar. A analise pode demorar a depender do tamanho do exe analisado e do seu pc tbm. Seguem alguns prints. bom é isso... /* * ============================================================================ * Vtable Analyzer Pro v5.3 - By Guilherme Candiotto * MSVC RTTI / vtable harvester for IDA Free 9.x and IDA Pro 7.x+ * ============================================================================ * * WHAT IT DOES * ------------ * Detects C++ classes in MSVC binaries via RTTI (CompleteObjectLocator), * reconstructs the inheritance hierarchy (including multi-inheritance via * secondary vtables), names virtual methods, applies __thiscall + this * typing for Hex-Rays, infers sizeof, detects singletons, annotates * virtual call sites, and emits a C++ header with the recovered classes. * * HOW TO USE * ---------- * File > Script file... -> select this .idc * * Outputs in <OUTPUT_DIR>: * vtables_analysis.json structured class data (parents, methods, ...) * vtables_analysis.log plain-text run log * vtables_overrides.json override relationships (child slot -> parent) * wyd_classes.h C++ header with reconstructed classes * * Re-run with Alt+F5 (configurable via REGISTER_HOTKEY). * * REQUIREMENTS * ------------ * IDA Free 9.x or IDA Pro >= 7.x. * MSVC binary with RTTI enabled (CompleteObjectLocator present). * Tested on x86; x64 supported via BRUTE_FORCE_X64_RVA path. * * CONFIG * ------ * See #defines below. Each one is documented at its declaration. * * License: MIT. Use freely; attribution appreciated. * ============================================================================ */ #include <idc.idc> // ---------------------- CONFIG ---------------------- // Pasta onde gravar os arquivos de saida. // "" = mesma pasta do .idb (recomendado). // "D:/path" = caminho absoluto. Use / ou \\ no Windows. #define OUTPUT_DIR "" #define OUTPUT_JSON_NAME "vtables_analysis.json" // structured class data (parents, methods, sizeof, ...) #define OUTPUT_LOG_NAME "vtables_analysis.log" // plain-text run log (progress + warnings) #define OUTPUT_OVERRIDES_NAME "vtables_overrides.json" // override map: child slot -> parent function #define OUTPUT_HEADER_NAME "wyd_classes.h" // C++ header with reconstructed classes (importable in IDA Local Types) #define DRY_RUN 0 // 1 = preview only (no IDB modification, no file writes) #define CREATE_STRUCTS 1 // 1 = create opaque <Class>_t struct in IDA (vptr at offset 0) #define RENAME_OVERRIDES 0 // 1 = rename even functions with existing custom names (e.g. from PDB); 0 = preserve them #define SCAN_DATA_TOO 1 // 1 = scan .data segment too (some binaries have vtables there, not just .rdata) #define STRING_FIRST_SCAN 1 // 1 = scan via RTTI strings (.?AV/.?AU), reconstruct TD/COL/vtable from xrefs #define POINTER_FIRST_SCAN 1 // 1 = sequential DWORD scan in .rdata looking for TD->COL pointer pattern (classic mode) #define PROPAGATE_OVERRIDES 1 // 1 = final pass detecting overrides (child slot != parent func) vs inherited methods #define BRUTE_FORCE_X64_RVA 1 // so executa em x64; inerte em x86 #define BRUTE_FORCE_X86 1 // varredura simetrica para x86 (sig=0) #define APPLY_THISCALL_TYPES 1 // aplica __thiscall(_t *this) nos vmethods #define DETECT_OBJECT_SIZES 1 // tenta deduzir sizeof via operator new #define DETECT_SINGLETONS 1 // marca globais que recebem instancias #define ANNOTATE_VCALLS 1 // comenta call [reg+N] com possibilidades #define EMIT_CPP_HEADER 1 // emite wyd_classes.h #define VCALL_MAX_METHODS 4 // max metodos listados por slot #define MAX_VTABLE_METHODS 2048 // safety cap: vtables larger than this are rejected (likely false positives) #define MIN_VTABLE_METHODS 1 // minimum slots to consider a vtable valid // v5.2 ---- #define CLEAR_OUTPUT_ON_START 1 // limpa Output do IDA no inicio #define REGISTER_HOTKEY 1 // Alt+F5 re-roda o script #define HOTKEY_COMBO "Alt-F5" // hotkey to re-run the script (IDA hotkey syntax: "Mod-Key") #define PROGRESS_EVERY 4096 // emite msg() a cada N iteracoes // v5.3: filtro de classes framework (MFC/STL/ATL/etc) #define EXCLUDE_FRAMEWORK_CLASSES 1 // 1 = pula MFC, STL, ATL, Gdiplus... // v5.3: detectores melhorados #define SIZE_INFER_FROM_BODY 1 // estima sizeof pelo max [this+N] no ctor #define SIZE_BODY_SCAN_LIMIT 80 // max instrucoes a olhar no body do ctor #define SINGLETON_AGGRESSIVE 1 // tenta padroes adicionais alem do basico // v5.3: limite de varredura para string-first scan (evita travar em // binarios de servidor com .data gigante (>100MB de tabelas de jogo). // 0 = sem limite. Default: 50MB. #define STRING_SCAN_MAX_SEG_SIZE 0x3200000 // 50MB // Cores BGR usadas pra colorir cada tipo de item no Disassembly View do IDA. // Formato: 0xBBGGRR. Mude pra 0 pra desabilitar coloracao especifica. #define COLOR_VTABLE_SLOT 0xFFE8E0 #define COLOR_VFUNC 0xE0FFE0 #define COLOR_PURE 0xC0C0C0 #define COLOR_DTOR 0xC0C0FF #define COLOR_CTOR 0xC0FFFF #define COLOR_RTTI_COL 0xE0E0FF #define COLOR_TYPE_DESC 0xFFE0FF #define COLOR_OVERRIDE 0xE0FFFF // Nomes de arrays internos do IDB (mantem cache entre runs do script). // Mude o sufixo (_v5_/_v4_) se quiser invalidar o cache forcando re-scan. #define ARR_VT_SEEN "vap_v4_vt_seen" #define ARR_TD2VT "vap_v4_td2vt" #define ARR_VT2TD "vap_v4_vt2td" #define ARR_VT2COL "vap_v4_vt2col" #define ARR_VT2COUNT "vap_v4_vt2count" #define ARR_VT2NAME "vap_v4_vt2name" #define ARR_VT2PARENTS "vap_v4_vt2parents" #define ARR_VT_LIST "vap_v4_vt_list" #define ARR_VT2OFFSET "vap_v5_vt2offset" // COL.offset (0=primary) #define ARR_VT2SIZE "vap_v5_vt2size" #define ARR_VT2SINGLETON "vap_v5_vt2singleton" #define ARR_SLOT_METHODS "vap_v5_slot_methods" #define ARR_HDR_EMITTED "vap_v5_hdr_emitted" #define ARR_TOPO_VISITED "vap_v5_topo_visited" #define ARR_TOPO_ORDER "vap_v5_topo_order" #define ARR_TOPO_COUNT "vap_v5_topo_count" // ---------------------- GLOBAIS ---------------------- // FIX IDC 9.x: variaveis globais usam "extern", nao "static" (que eh // reservado pra funcoes). Senao o parser cuspia "Missing brace". extern g_ptr_size; extern g_is_64; extern g_imagebase; extern g_log_handle; extern g_json_handle; extern g_overrides_handle; extern g_json_first; extern g_overrides_first; extern g_vt_list_count; extern g_stat_classes; extern g_stat_methods; extern g_stat_renamed; extern g_stat_ctors; extern g_stat_dtors; extern g_stat_pures; extern g_stat_overrides; extern g_stat_inherited; extern g_stat_brute; extern g_stat_thiscall; extern g_stat_sizes; extern g_stat_singletons; extern g_stat_vcalls; extern g_stat_header_classes; extern g_stat_renamed_inherited; extern g_stat_errors; extern g_purecall_csv; extern g_stat_filtered; // ========================================================================= // user_cancelled() - cooperative cancel hook (IDC stub) // ========================================================================= // IDC 9.x removed the wait_box / user_cancelled API; only IDAPython still // exposes it (idaapi.user_cancelled / ida_kernwin.user_cancelled). // // This stub always returns 0, so the if (user_cancelled()) checks scattered // across the heavy scan loops below are dead code - a long run cannot be // aborted gracefully from IDC (you have to kill the IDA process). // // TO ENABLE REAL CANCEL SUPPORT (IDAPython port): // 1. Wrap this script as an IDAPython plugin (.py instead of .idc). // 2. Replace this stub with: // import ida_kernwin // def user_cancelled(): // return ida_kernwin.user_cancelled() // 3. Bracket the main() entry with: // ida_kernwin.show_wait_box("HIDECANCEL\nVtable Analyzer: running...") // try: // main() // finally: // ida_kernwin.hide_wait_box() // 4. The 10 existing `if (user_cancelled()) return;` calls in this script // will then start working as cooperative cancel points. // // Until then, this stub keeps the IDC source compatible and side-effect-free. // ========================================================================= static user_cancelled() { return 0; } // ========================================================================= // LOG // ========================================================================= static log_line(level, line) { auto stamp = "[" + level + "] " + line; msg("%s\n", stamp); if (g_log_handle != 0) fprintf(g_log_handle, "%s\n", stamp); } static log_info(line) { log_line("INFO", line); } static log_warn(line) { log_line("WARN", line); } static log_error(line) { log_line("ERR ", line); g_stat_errors = g_stat_errors + 1; } // ========================================================================= // PATH HELPERS // ========================================================================= static find_last_char(s, c) { if (s == 0 || s == "") return -1; auto i; auto last = -1; auto n = strlen(s); for (i = 0; i < n; i = i + 1) { if (substr(s, i, i + 1) == c) last = i; } return last; } static dirname_of(path) { if (path == 0 || path == "") return ""; auto p1 = find_last_char(path, "\\"); auto p2 = find_last_char(path, "/"); auto pos = (p1 > p2) ? p1 : p2; if (pos == -1) return ""; return substr(path, 0, pos); } static normalize_path(p) { if (p == 0 || p == "") return ""; auto out = ""; auto i; auto n = strlen(p); for (i = 0; i < n; i = i + 1) { auto c = substr(p, i, i + 1); if (c == "\\") out = out + "/"; else out = out + c; } return out; } static path_join(dir, name) { if (dir == "" || dir == 0) return name; auto d = normalize_path(dir); auto last = substr(d, strlen(d) - 1, strlen(d)); if (last == "/") return d + name; return d + "/" + name; } static resolve_output_dir() { if (OUTPUT_DIR != "" && OUTPUT_DIR != 0) return normalize_path(OUTPUT_DIR); auto idb = get_idb_path(); auto d = dirname_of(idb); if (d == "" || d == 0) return "."; return normalize_path(d); } static safe_fopen(path, mode) { auto h = fopen(path, mode); if (h == 0) { msg("[ERR ] FOPEN FALHOU: '%s' (modo '%s')\n", path, mode); msg(" -> Verifique se a pasta existe e tem permissao de escrita.\n"); msg(" -> Ajuste OUTPUT_DIR no topo do script se necessario.\n"); return 0; } msg("[INFO] arquivo aberto OK: %s\n", path); return h; } // ========================================================================= // HELPERS BASICOS // ========================================================================= static read_ptr(ea) { return g_is_64 ? get_qword(ea) : get_dword(ea); } static rva_to_ea(rva) { return g_imagebase + rva; } static seg_is_executable(ea) { if (!is_loaded(ea)) return 0; return (get_segm_attr(ea, SEGATTR_PERM) & SEGPERM_EXEC) != 0; } static seg_name_of(ea) { if (!is_loaded(ea)) return ""; return get_segm_name(ea); } static is_valid_code_ptr(ea) { if (ea == BADADDR || ea == 0) return 0; if (!is_loaded(ea)) return 0; return seg_is_executable(ea); } static is_valid_data_ptr(ea) { if (ea == BADADDR || ea == 0) return 0; return is_loaded(ea); } static starts_with(s, prefix) { if (s == 0 || prefix == 0) return 0; if (strlen(s) < strlen(prefix)) return 0; return substr(s, 0, strlen(prefix)) == prefix; } static ends_with(s, suffix) { if (s == 0 || suffix == 0) return 0; auto sl = strlen(s); auto pl = strlen(suffix); if (sl < pl) return 0; return substr(s, sl - pl, sl) == suffix; } static sanitize_name(s) { if (s == 0 || s == "") return "anon"; auto out = ""; auto i; auto n = strlen(s); for (i = 0; i < n; i = i + 1) { auto c = substr(s, i, i + 1); if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z") || (c >= "0" && c <= "9") || c == "_") { out = out + c; } else if (c == ":" || c == "<" || c == ">" || c == "," || c == " " || c == "*" || c == "&" || c == "(" || c == ")" || c == "[" || c == "]" || c == "-" || c == "." || c == "+" || c == "/" || c == "\\" || c == "$" || c == "@" || c == "?") { out = out + "_"; } } if (out == "") out = "anon"; return out; } // ========================================================================= // JSON ESCAPING // ========================================================================= static json_escape(s) { if (s == 0 || s == "") return ""; auto out = ""; auto i; auto n = strlen(s); for (i = 0; i < n; i = i + 1) { auto c = substr(s, i, i + 1); if (c == "\"") out = out + "\\\""; else if (c == "\\") out = out + "\\\\"; else if (c == "\n") out = out + "\\n"; else if (c == "\r") out = out + "\\r"; else if (c == "\t") out = out + "\\t"; else out = out + c; } return out; } // ========================================================================= // PURECALL ADDRESS LOOKUP (cache de enderecos conhecidos via imports) // ========================================================================= static csv_contains_long(csv, val) { if (csv == "" || csv == 0) return 0; auto buf = ""; auto i; auto n = strlen(csv); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(csv, i, i + 1) : ","; if (c == ",") { if (buf != "" && atol(buf) == val) return 1; buf = ""; } else { buf = buf + c; } } return 0; } static csv_append_long(csv, val) { if (csv == "") return ltoa(val, 10); return csv + "," + ltoa(val, 10); } static init_purecall_addresses() { g_purecall_csv = ""; auto names_buf = "__purecall|_purecall|purecall|__cxa_pure_virtual|_cxa_pure_virtual"; auto buf = ""; auto i; auto n = strlen(names_buf); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(names_buf, i, i + 1) : "|"; if (c == "|") { if (buf != "") { auto ea = get_name_ea_simple(buf); if (ea != BADADDR && !csv_contains_long(g_purecall_csv, ea)) { g_purecall_csv = csv_append_long(g_purecall_csv, ea); } } buf = ""; } else { buf = buf + c; } } } static is_known_purecall_addr(ea) { return csv_contains_long(g_purecall_csv, ea); } // ========================================================================= // PARSER MANUAL DO NOME MANGLED (com tratamento de templates) // // .?AV<Classe>@<NS_inner>@<NS_outer>@@ // .?AU<Struct>@<NS_inner>@<NS_outer>@@ // // Resultado em C++ pseudo: NS_outer::NS_inner::Classe // Templates "?$Nome@..." viram "tpl_Nome" para nao quebrar o sanitize. // ========================================================================= static cleanup_template_segment(seg) { if (!starts_with(seg, "?$")) return seg; auto rest = substr(seg, 2, strlen(seg)); auto pos = strstr(rest, "@"); auto name; if (pos != -1) name = substr(rest, 0, pos); else name = rest; if (name == "") name = "tpl"; return "tpl_" + name; } static manual_parse_rtti_name(mangled) { if (mangled == 0 || mangled == "") return ""; if (strlen(mangled) < 6) return ""; auto prefix = substr(mangled, 0, 4); if (prefix != ".?AV" && prefix != ".?AU") return ""; auto rest = substr(mangled, 4, strlen(mangled)); if (!ends_with(rest, "@@")) return ""; rest = substr(rest, 0, strlen(rest) - 2); if (rest == "") return ""; auto i; auto n = strlen(rest); auto cur = ""; auto result = ""; for (i = 0; i < n; i = i + 1) { auto c = substr(rest, i, i + 1); if (c == "@") { if (cur != "") { auto seg = cleanup_template_segment(cur); if (result == "") result = seg; else result = seg + "::" + result; } cur = ""; } else { cur = cur + c; } } if (cur != "") { auto seg2 = cleanup_template_segment(cur); if (result == "") result = seg2; else result = seg2 + "::" + result; } return result; } // ========================================================================= // v5.2: leitor de string C RAW (le bytes ate \0 sem depender do IDA // ter definido a string). Substitui o que create_strlit fazia, agora // que essa funcao mudou de assinatura no 9.x e nao podemos mais usar. // ========================================================================= static read_c_string_raw(ea) { if (!is_loaded(ea)) return ""; auto out = ""; auto i = 0; auto max_len = 512; while (i < max_len) { auto b = get_wide_byte(ea + i); if (b == 0) break; if (b < 0x20 || b > 0x7E) break; out = out + sprintf("%c", b); i = i + 1; } return out; } // ========================================================================= // RTTI - CompleteObjectLocator (COL) // +0x00 signature (0 = x86, 1 = x64) // +0x04 offset // +0x08 cdOffset // +0x0C pTypeDescriptor (RVA em x64, ptr em x86) // +0x10 pClassDescriptor(RVA em x64, ptr em x86) // +0x14 pSelf (so x64, RVA) // ========================================================================= static col_read_field(col_ea, off) { auto v = get_wide_dword(col_ea + off); if (g_is_64) return rva_to_ea(v); return v; } static validate_col(col_ea) { if (!is_valid_data_ptr(col_ea)) return 0; auto sig = get_wide_dword(col_ea); auto expected = g_is_64 ? 1 : 0; if (sig != expected) return 0; auto offset = get_wide_dword(col_ea + 0x04); auto cdOffset = get_wide_dword(col_ea + 0x08); if (offset > 0x10000) return 0; if (cdOffset > 0x10000) return 0; auto type_desc = col_read_field(col_ea, 0x0C); if (!is_valid_data_ptr(type_desc)) return 0; auto chd = col_read_field(col_ea, 0x10); if (!is_valid_data_ptr(chd)) return 0; auto chd_sig = get_wide_dword(chd); if (chd_sig != 0) return 0; auto nb = get_wide_dword(chd + 0x08); if (nb == 0 || nb > 256) return 0; if (g_is_64) { auto self_rva = get_wide_dword(col_ea + 0x14); if (rva_to_ea(self_rva) != col_ea) return 0; } return 1; } static read_typedesc_name(td_ea) { if (!is_valid_data_ptr(td_ea)) return ""; auto name_ea = td_ea + (g_ptr_size * 2); auto mangled = get_strlit_contents(name_ea, -1, STRTYPE_C); if (mangled == 0 || mangled == "") { mangled = read_c_string_raw(name_ea); } if (mangled == 0 || mangled == "") return ""; return mangled; } static demangle_class_name(mangled) { if (mangled == 0 || mangled == "") return ""; if (!starts_with(mangled, ".?AV") && !starts_with(mangled, ".?AU")) return ""; auto wrapped = "??_R0" + substr(mangled, 1, strlen(mangled)) + "@8"; auto dem = demangle_name(wrapped, INF_LONG_DN); if (dem != 0 && dem != "") { if (starts_with(dem, "class ")) dem = substr(dem, 6, strlen(dem)); if (starts_with(dem, "struct ")) dem = substr(dem, 7, strlen(dem)); auto suf = " `RTTI Type Descriptor'"; if (ends_with(dem, suf)) dem = substr(dem, 0, strlen(dem) - strlen(suf)); if (dem != "") return dem; } auto man = manual_parse_rtti_name(mangled); if (man != "") return man; return mangled; } // ========================================================================= // CHD + BaseClassArray -> lista de pais (TD addresses CSV) // // CHD: // +0x00 signature (==0) // +0x04 attributes // +0x08 numBaseClasses // +0x0C pBaseClassArray (RVA x64 / ptr x86) // // BCD (cada entrada da BCA aponta pra um BCD): // +0x00 pTypeDescriptor // +0x04 numContainedBases // +0x08 PMD (mdisp, pdisp, vdisp - 12 bytes) // +0x14 attributes // +0x18 pClassDescriptor // // BCA[0] eh sempre a propria classe; pulamos. // ========================================================================= static parse_base_classes(col_ea) { auto chd = col_read_field(col_ea, 0x10); if (!is_valid_data_ptr(chd)) return ""; auto sig = get_wide_dword(chd); if (sig != 0) return ""; auto num_bases = get_wide_dword(chd + 0x08); if (num_bases <= 1 || num_bases > 64) return ""; auto bca_field = get_wide_dword(chd + 0x0C); auto bca_ea = g_is_64 ? rva_to_ea(bca_field) : bca_field; if (!is_valid_data_ptr(bca_ea)) return ""; auto out = ""; auto i; for (i = 1; i < num_bases; i = i + 1) { auto bcd_field = get_wide_dword(bca_ea + i * 4); auto bcd_ea = g_is_64 ? rva_to_ea(bcd_field) : bcd_field; if (!is_valid_data_ptr(bcd_ea)) continue; auto td_field = get_wide_dword(bcd_ea); auto td_ea = g_is_64 ? rva_to_ea(td_field) : td_field; if (!is_valid_data_ptr(td_ea)) continue; if (out == "") out = ltoa(td_ea, 10); else out = out + "," + ltoa(td_ea, 10); } return out; } static parents_csv_to_names(csv) { if (csv == "" || csv == 0) return ""; auto out = ""; auto buf = ""; auto i; auto n = strlen(csv); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(csv, i, i + 1) : ","; if (c == ",") { if (buf != "") { auto td = atol(buf); auto mang = read_typedesc_name(td); auto nm = (mang != "") ? demangle_class_name(mang) : "??"; if (out == "") out = nm; else out = out + ", " + nm; } buf = ""; } else { buf = buf + c; } } return out; } // ========================================================================= // CACHE + HIERARQUIA (arrays do IDB) // ========================================================================= static arr_init(name) { auto id = get_array_id(name); if (id != -1) delete_array(id); create_array(name); } static arr_set_long(name, key, val) { auto id = get_array_id(name); if (id == -1) return; set_array_long(id, key, val); } static arr_get_long(name, key) { auto id = get_array_id(name); if (id == -1) return -1; return get_array_element(AR_LONG, id, key); } static arr_set_str(name, key, val) { auto id = get_array_id(name); if (id == -1) return; set_array_string(id, key, val); } static arr_get_str(name, key) { auto id = get_array_id(name); if (id == -1) return ""; auto v = get_array_element(AR_STR, id, key); if (v == 0 || v == -1) return ""; return v; } static cache_init() { arr_init(ARR_VT_SEEN); arr_init(ARR_TD2VT); arr_init(ARR_VT2TD); arr_init(ARR_VT2COL); arr_init(ARR_VT2COUNT); arr_init(ARR_VT2NAME); arr_init(ARR_VT2PARENTS); arr_init(ARR_VT_LIST); arr_init(ARR_VT2SIZE); arr_init(ARR_VT2SINGLETON); arr_init(ARR_VT2OFFSET); g_vt_list_count = 0; } static cache_seen(ea) { return arr_get_long(ARR_VT_SEEN, ea) > 0; } static cache_mark(ea) { arr_set_long(ARR_VT_SEEN, ea, 1); } static hier_register(td_ea, vt_ea, col_ea, sname, count, parents_csv, col_offset) { arr_set_long(ARR_VT2TD, vt_ea, td_ea); arr_set_long(ARR_VT2COL, vt_ea, col_ea); arr_set_long(ARR_VT2COUNT, vt_ea, count); arr_set_long(ARR_VT2OFFSET, vt_ea, col_offset); arr_set_str (ARR_VT2NAME, vt_ea, sname); arr_set_str (ARR_VT2PARENTS,vt_ea, parents_csv); arr_set_long(ARR_VT_LIST, g_vt_list_count, vt_ea); g_vt_list_count = g_vt_list_count + 1; if (col_offset == 0) { if (arr_get_long(ARR_TD2VT, td_ea) <= 0) { arr_set_long(ARR_TD2VT, td_ea, vt_ea); } } } static hier_offset(vt_ea) { auto v = arr_get_long(ARR_VT2OFFSET, vt_ea); if (v == -1) return 0; return v; } static hier_col(vt_ea) { auto v = arr_get_long(ARR_VT2COL, vt_ea); if (v == -1) return BADADDR; return v; } static hier_vt_by_td(td_ea) { auto v = arr_get_long(ARR_TD2VT, td_ea); if (v == -1) return BADADDR; return v; } static hier_count(vt_ea) { auto v = arr_get_long(ARR_VT2COUNT, vt_ea); if (v == -1) return 0; return v; } static hier_name(vt_ea) { return arr_get_str(ARR_VT2NAME, vt_ea); } static hier_parents(vt_ea) { return arr_get_str(ARR_VT2PARENTS, vt_ea); } static hier_vt_at(idx) { auto v = arr_get_long(ARR_VT_LIST, idx); if (v == -1) return BADADDR; return v; } // ========================================================================= // PURECALL // ========================================================================= static is_pure_call(faddr) { if (faddr == BADADDR || faddr == 0) return 0; if (is_known_purecall_addr(faddr)) return 1; auto name = get_func_name(faddr); if (name != 0 && name != "") { if (strstr(name, "purecall") != -1) return 1; if (strstr(name, "pure_virtual") != -1) return 1; if (strstr(name, "cxa_pure_virtual") != -1) return 1; } auto fend = get_func_attr(faddr, FUNCATTR_END); if (fend == BADADDR) return 0; if ((fend - faddr) > 24) return 0; auto mnem = print_insn_mnem(faddr); if (mnem == "int" || mnem == "hlt" || mnem == "ud2") return 1; if (mnem == "jmp") { auto dref = get_first_dref_from(faddr); while (dref != BADADDR) { auto target_via_iat = get_wide_dword(dref); if (g_is_64) target_via_iat = get_qword(dref); if (is_known_purecall_addr(target_via_iat)) return 1; auto dn = get_name(dref); if (dn != 0 && dn != "") { if (strstr(dn, "purecall") != -1) return 1; if (strstr(dn, "pure_virtual") != -1) return 1; } dref = get_next_dref_from(faddr, dref); } auto tgt = get_first_fcref_from(faddr); if (tgt != BADADDR) { if (is_known_purecall_addr(tgt)) return 1; auto tn = get_func_name(tgt); if (tn != 0 && tn != "") { if (strstr(tn, "purecall") != -1) return 1; if (strstr(tn, "pure_virtual") != -1) return 1; } } } return 0; } // ========================================================================= // DESTRUTOR // ========================================================================= static is_destructor(faddr) { if (faddr == BADADDR || faddr == 0) return 0; auto name = get_func_name(faddr); if (name != 0 && name != "") { if (strstr(name, "::~") != -1) return 1; if (strstr(name, "??1") != -1) return 1; if (strstr(name, "??_E") != -1) return 1; if (strstr(name, "??_G") != -1) return 1; if (strstr(name, "destructor") != -1) return 1; if (strstr(name, "scalar_dtor")!= -1) return 1; if (strstr(name, "vector_dtor")!= -1) return 1; if (strstr(name, "__dtor") != -1) return 1; } auto fend = get_func_attr(faddr, FUNCATTR_END); if (fend == BADADDR) return 0; if ((fend - faddr) > 0x200) return 0; auto ea = faddr; auto guard = 0; while (ea < fend && ea != BADADDR && guard < 80) { auto m = print_insn_mnem(ea); if (m == "call" || m == "jmp") { auto tgt = get_first_fcref_from(ea); if (tgt != BADADDR) { auto tn = get_func_name(tgt); if (tn != 0 && tn != "") { if (strstr(tn, "operator delete") != -1) return 1; if (strstr(tn, "??3@") != -1) return 1; if (strstr(tn, "??_V") != -1) return 1; if (tn == "_free" || tn == "free" || tn == "_free_base") return 1; } } } ea = next_head(ea, fend); guard = guard + 1; } return 0; } // ========================================================================= // DETECCAO DE SIZEOF VIA operator new // Pattern em x86 thiscall: // push <imm> ; size // call ?? operator new // add esp, 4 ; (opcional) // mov ecx, eax ; this = obj // call <ctor> // ========================================================================= static find_object_size_from_call(call_ea) { auto fstart = get_func_attr(call_ea, FUNCATTR_START); if (fstart == BADADDR) fstart = call_ea - 0x80; auto cur = call_ea; auto guard = 0; while (guard < 15) { cur = prev_head(cur, fstart); if (cur == BADADDR || cur == 0 || cur < fstart) break; auto m = print_insn_mnem(cur); if (m == "ret" || m == "jmp") break; if (m == "call") { auto tgt = get_first_fcref_from(cur); if (tgt != BADADDR) { auto tn = get_func_name(tgt); if (tn != 0 && tn != "") { auto is_alloc = 0; if (strstr(tn, "operator new") != -1) is_alloc = 1; if (strstr(tn, "??2@") != -1) is_alloc = 1; if (strstr(tn, "_malloc") != -1) is_alloc = 1; if (tn == "malloc" || tn == "_malloc") is_alloc = 1; if (is_alloc) { auto pcur = cur; auto pg = 0; while (pg < 6) { pcur = prev_head(pcur, fstart); if (pcur == BADADDR || pcur < fstart) break; auto pm = print_insn_mnem(pcur); if (!g_is_64 && pm == "push" && get_operand_type(pcur, 0) == o_imm) { return get_operand_value(pcur, 0); } if (g_is_64 && pm == "mov" && get_operand_type(pcur, 0) == o_reg && get_operand_type(pcur, 1) == o_imm) { auto v = get_operand_value(pcur, 1); if (v > 0 && v < 0x10000) return v; } pg = pg + 1; } } } } return 0; } guard = guard + 1; } return 0; } static find_object_size_for_ctor(ctor_ea) { auto xr = get_first_cref_to(ctor_ea); while (xr != BADADDR) { auto sz = find_object_size_from_call(xr); if (sz > 0 && sz < 0x10000) return sz; xr = get_next_cref_to(ctor_ea, xr); } return 0; } // ========================================================================= // DETECCAO DE SINGLETON // Heuristica: depois da call ao construtor, se ha "mov ds:G, eax" com G // sendo um global valido, marca G como instancia singleton da classe. // ========================================================================= // Marca um global como singleton da classe. static mark_singleton(g_ea, class_name, ctor_ea) { if (DRY_RUN) return; auto cur_name = get_name(g_ea); if (cur_name == "" || starts_with(cur_name, "dword_") || starts_with(cur_name, "qword_") || starts_with(cur_name, "byte_") || starts_with(cur_name, "off_") || starts_with(cur_name, "unk_")) { set_name(g_ea, "g_" + class_name + "_instance", SN_NOWARN | SN_FORCE); } set_cmt(g_ea, "Singleton " + class_name + " ctor=0x" + ltoa(ctor_ea, 16), 1); } static detect_singleton_for_ctor(ctor_ea, class_name) { auto xr = get_first_cref_to(ctor_ea); while (xr != BADADDR) { auto caller_end = get_func_attr(xr, FUNCATTR_END); if (caller_end == BADADDR) caller_end = xr + 0x100; auto tracked = "|eax|rax|ecx|rcx|"; auto guard = 0; auto cur = xr; while (guard < 8) { cur = next_head(cur, caller_end); if (cur == BADADDR || cur >= caller_end) break; auto m = print_insn_mnem(cur); if (m == "call" || m == "ret" || m == "jmp") break; if (m == "mov") { auto t0 = get_operand_type(cur, 0); auto t1 = get_operand_type(cur, 1); if (t0 == o_mem && t1 == o_reg) { auto src_needle = "|" + print_operand(cur, 1) + "|"; if (strstr(tracked, src_needle) != -1) { auto g_ea = get_operand_value(cur, 0); if (is_loaded(g_ea) && g_ea > 0x1000) { mark_singleton(g_ea, class_name, ctor_ea); return g_ea; } } } if (t0 == o_reg && t1 == o_reg) { auto src_needle2 = "|" + print_operand(cur, 1) + "|"; if (strstr(tracked, src_needle2) != -1) { auto dst_needle = "|" + print_operand(cur, 0) + "|"; if (strstr(tracked, dst_needle) == -1) { tracked = tracked + substr(dst_needle, 1, strlen(dst_needle)); } } } } guard = guard + 1; } xr = get_next_cref_to(ctor_ea, xr); } return BADADDR; } // ========================================================================= // APLICACAO DE __thiscall + tipo "this" NAS FUNCOES VIRTUAIS // ========================================================================= // FIX A1: nao caimos mais em SetType (pode nao existir em IDA 9.x). // FIX A2: usamos TINFO_GUESSED (0) para nao sobrescrever tipos que o // usuario tenha definido manualmente. static apply_type_safe(ea, decl) { auto ti = parse_decl(decl, 0); if (ti == 0) return 0; return apply_type(ea, ti, 0); } static ensure_class_struct(sname_class) { auto sname = sname_class + "_t"; auto sid = get_struc_id(sname); if (sid != BADADDR) return sid; sid = add_struc(-1, sname, 0); if (sid == BADADDR) return BADADDR; auto flag = g_is_64 ? (FF_QWORD | FF_DATA) : (FF_DWORD | FF_DATA); add_struc_member(sid, "vptr", 0, flag, -1, g_ptr_size); return sid; } static apply_thiscall_to_vtable(vt_ea) { if (!APPLY_THISCALL_TYPES || DRY_RUN) return 0; auto sname = hier_name(vt_ea); auto count = hier_count(vt_ea); if (sname == "" || count == 0) return 0; auto effective_sname = sname; auto col_offset = hier_offset(vt_ea); if (col_offset != 0) { auto col = hier_col(vt_ea); if (col != BADADDR) { auto ptd = find_parent_td_for_offset(col, col_offset); if (ptd != 0) { auto pvt = hier_vt_by_td(ptd); if (pvt != BADADDR) { auto pn = hier_name(pvt); if (pn != "") effective_sname = pn; } } } } auto sid = ensure_class_struct(effective_sname); if (sid == BADADDR) return 0; auto applied = 0; auto i; for (i = 0; i < count; i = i + 1) { auto slot = vt_ea + i * g_ptr_size; auto faddr = read_ptr(slot); if (faddr == 0 || faddr == BADADDR) continue; if (is_pure_call(faddr)) continue; auto decl = "void __thiscall sub(struct " + effective_sname + "_t *this);"; if (apply_type_safe(faddr, decl)) applied = applied + 1; } return applied; } static apply_all_thiscall_types() { if (!APPLY_THISCALL_TYPES) return; log_info("=== Aplicando __thiscall + tipo this (em ordem topologica) ==="); auto tcount = topo_count(); auto total = (tcount > 0) ? tcount : g_vt_list_count; auto i; for (i = 0; i < total; i = i + 1) { if (user_cancelled()) return; auto vt = (tcount > 0) ? topo_at(i) : hier_vt_at(i); if (vt != BADADDR) { auto n = apply_thiscall_to_vtable(vt); g_stat_thiscall = g_stat_thiscall + n; } if ((i & 0x1F) == 0) { msg("[thiscall] %d/%d classes | %d metodos\n", i, total, g_stat_thiscall); } } log_info("__thiscall aplicado em " + ltoa(g_stat_thiscall, 10) + " metodos"); } // ========================================================================= // ANOTACAO DE CHAMADAS VIRTUAIS (call dword ptr [reg+N]) // ========================================================================= // // Plausibilidade v2: rastreia o registrador-base do call ate sua origem. // // 1) extrai o reg-base de "call [reg+N]" (ex: "eax" em "[eax+0Ch]") // 2) caminha pra tras ate o inicio da funcao (ou ate ret/jmp/call), // acompanhando o conjunto de regs que carregam aquele valor (lida // com propagacoes "mov ebx, eax" ao longo do prologo) // 3) declara plausivel quando encontra o write final que veio de // memoria (mov reg, [reg2+disp] ou lea reg, [reg2+disp]) - o // vptr load // 4) se o write veio de imediato/aritmetica/etc, descarta // // Janela aumentada pra 32 instrucoes (ou ate o inicio da funcao). // ========================================================================= static get_call_displ_base_reg(ea) { auto op = print_operand(ea, 0); if (op == 0 || op == "") return ""; auto bp = strstr(op, "["); if (bp == -1) return ""; auto i = bp + 1; auto n = strlen(op); auto reg = ""; while (i < n) { auto c = substr(op, i, i + 1); if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z") || (c >= "0" && c <= "9")) { reg = reg + c; } else { break; } i = i + 1; } return reg; } static is_likely_vcall(call_ea) { auto call_reg = get_call_displ_base_reg(call_ea); if (call_reg == "") return 0; auto fstart = get_func_attr(call_ea, FUNCATTR_START); if (fstart == BADADDR) fstart = call_ea - 0x100; auto tracked = "|" + call_reg + "|"; auto cur = call_ea; auto guard = 0; while (guard < 32) { cur = prev_head(cur, fstart); if (cur == BADADDR || cur < fstart) break; auto m = print_insn_mnem(cur); if (m == "ret" || m == "jmp" || m == "call") break; if (m == "mov" || m == "lea") { auto t0 = get_operand_type(cur, 0); if (t0 == o_reg) { auto dst = print_operand(cur, 0); auto dst_needle = "|" + dst + "|"; if (strstr(tracked, dst_needle) != -1) { auto t1 = get_operand_type(cur, 1); if (t1 == o_phrase || t1 == o_displ) return 1; if (t1 == o_reg) { auto src = print_operand(cur, 1); auto src_needle = "|" + src + "|"; if (strstr(tracked, src_needle) == -1) { tracked = tracked + substr(src_needle, 1, strlen(src_needle)); } } else { return 0; } } } } guard = guard + 1; } return 0; } static build_slot_methods_map() { arr_init(ARR_SLOT_METHODS); auto i; for (i = 0; i < g_vt_list_count; i = i + 1) { auto vt = hier_vt_at(i); if (vt == BADADDR) continue; auto sname = hier_name(vt); auto count = hier_count(vt); auto j; for (j = 0; j < count; j = j + 1) { auto cur = arr_get_str(ARR_SLOT_METHODS, j); if (cur == "") { arr_set_str(ARR_SLOT_METHODS, j, sname); } else { if (strlen(cur) < 400) { arr_set_str(ARR_SLOT_METHODS, j, cur + "," + sname); } } } } } static get_slot_summary(slot) { auto cur = arr_get_str(ARR_SLOT_METHODS, slot); if (cur == "") return ""; auto out = ""; auto buf = ""; auto emitted = 0; auto total = 0; auto i; auto n = strlen(cur); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(cur, i, i + 1) : ","; if (c == ",") { if (buf != "") { total = total + 1; if (emitted < VCALL_MAX_METHODS) { if (out != "") out = out + ", "; out = out + buf + "::v" + ltoa(slot, 10); emitted = emitted + 1; } } buf = ""; } else { buf = buf + c; } } if (total > VCALL_MAX_METHODS) { out = out + " (+" + ltoa(total - VCALL_MAX_METHODS, 10) + " mais)"; } return out; } static annotate_virtual_calls() { if (!ANNOTATE_VCALLS || DRY_RUN) return; log_info("=== Anotando chamadas virtuais ==="); build_slot_methods_map(); auto annotated = 0; auto func_count = 0; auto f = get_next_func(0); while (f != BADADDR) { if (user_cancelled()) return; func_count = func_count + 1; auto end = get_func_attr(f, FUNCATTR_END); auto ea = f; while (ea < end && ea != BADADDR) { auto m = print_insn_mnem(ea); if (m == "call" && get_operand_type(ea, 0) == o_displ) { auto disp = get_operand_value(ea, 0); if (disp >= 0 && disp < 0x800 && (disp - ((disp / g_ptr_size) * g_ptr_size)) == 0) { auto slot = disp / g_ptr_size; auto summary = get_slot_summary(slot); if (summary != "" && is_likely_vcall(ea)) { auto cur_cmt = get_cmt(ea, 0); auto can_set = 0; if (cur_cmt == "" || cur_cmt == 0) can_set = 1; else if (starts_with(cur_cmt, "vcall ")) can_set = 1; if (can_set) { set_cmt(ea, "vcall slot[" + ltoa(slot, 10) + "]: " + summary, 0); annotated = annotated + 1; } } } } ea = next_head(ea, end); } f = get_next_func(f); if ((func_count & 0xFF) == 0) { msg("[vcall] %d funcoes | %d call sites anotados\n", func_count, annotated); } } g_stat_vcalls = annotated; log_info("vcall: " + ltoa(annotated, 10) + " call sites anotados"); } // ========================================================================= // GERACAO DE wyd_classes.h (topological) // ========================================================================= static emit_class_header_rec(hf, vt_ea) { if (arr_get_long(ARR_HDR_EMITTED, vt_ea) > 0) return; arr_set_long(ARR_HDR_EMITTED, vt_ea, 1); if (hier_offset(vt_ea) != 0) return; auto parents_csv = hier_parents(vt_ea); auto parent_names_buf = ""; auto parent_count = 0; auto buf = ""; auto i; auto n = strlen(parents_csv); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(parents_csv, i, i + 1) : ","; if (c == ",") { if (buf != "") { auto td = atol(buf); auto pvt = hier_vt_by_td(td); if (pvt != BADADDR) { emit_class_header_rec(hf, pvt); auto pname = hier_name(pvt); if (parent_names_buf == "") parent_names_buf = pname; else parent_names_buf = parent_names_buf + "|" + pname; parent_count = parent_count + 1; } } buf = ""; } else { buf = buf + c; } } auto cname = hier_name(vt_ea); auto count = hier_count(vt_ea); auto size = arr_get_long(ARR_VT2SIZE, vt_ea); auto sgl = arr_get_long(ARR_VT2SINGLETON, vt_ea); fprintf(hf, "// vtable=0x%x methods=%d", vt_ea, count); if (size > 0) fprintf(hf, " sizeof=0x%x", size); if (sgl != -1 && sgl != BADADDR) fprintf(hf, " singleton=0x%x", sgl); if (parent_count > 0) { fprintf(hf, " inherits="); auto pn = parent_names_buf; auto j; auto pbuf = ""; auto first_p = 1; auto pl = strlen(pn); for (j = 0; j <= pl; j = j + 1) { auto pc = (j < pl) ? substr(pn, j, j + 1) : "|"; if (pc == "|") { if (pbuf != "") { if (!first_p) fprintf(hf, ","); fprintf(hf, "%s", pbuf); first_p = 0; } pbuf = ""; } else { pbuf = pbuf + pc; } } } fprintf(hf, "\n"); fprintf(hf, "struct vtable_%s_t;\n", cname); fprintf(hf, "struct %s {\n", cname); fprintf(hf, " struct vtable_%s_t *vptr;\n", cname); if (size > g_ptr_size) { fprintf(hf, " char data[0x%x];\n", size - g_ptr_size); } fprintf(hf, " // %d virtual methods:\n", count); auto k; for (k = 0; k < count; k = k + 1) { auto slot = vt_ea + k * g_ptr_size; auto faddr = read_ptr(slot); auto fname = get_func_name(faddr); auto pos = strstr(fname, "__"); auto mp; if (pos != -1) mp = substr(fname, pos + 2, strlen(fname)); else if (fname != "" && fname != 0) mp = fname; else mp = "vmethod_" + ltoa(k, 10); fprintf(hf, " // [%d] @ 0x%x %s", k, faddr, mp); if (is_pure_call(faddr)) fprintf(hf, " (pure)"); fprintf(hf, "\n"); } fprintf(hf, "};\n\n"); g_stat_header_classes = g_stat_header_classes + 1; } static emit_cpp_header(out_path) { if (!EMIT_CPP_HEADER) return; log_info("=== Gerando header C++ ==="); auto hf = fopen(out_path, "w"); if (hf == 0) { log_warn("Nao consegui abrir " + out_path); return; } fprintf(hf, "// =====================================================\n"); fprintf(hf, "// Gerado por Vtable Analyzer Pro v5.1\n"); fprintf(hf, "// Total de classes: %d\n", g_vt_list_count); fprintf(hf, "// Use no IDA: File > Load file > Parse C header file...\n"); fprintf(hf, "// para importar como Local Types.\n"); fprintf(hf, "// =====================================================\n"); fprintf(hf, "\n#pragma pack(push, 1)\n\n"); arr_init(ARR_HDR_EMITTED); auto i; for (i = 0; i < g_vt_list_count; i = i + 1) { if (user_cancelled()) break; auto vt = hier_vt_at(i); if (vt != BADADDR) emit_class_header_rec(hf, vt); } fprintf(hf, "#pragma pack(pop)\n"); fclose(hf); log_info("Header gerado: " + out_path + " (" + ltoa(g_stat_header_classes, 10) + " classes)"); } // ========================================================================= // CONSTRUTOR / DESTRUTOR via xref // ========================================================================= static rename_constructors(vtable_ea, sname_class) { auto xr = get_first_dref_to(vtable_ea); auto ctor_idx = 0; auto dtor_idx = 0; auto first_ctor = BADADDR; while (xr != BADADDR) { auto fstart = get_func_attr(xr, FUNCATTR_START); auto xr_mnem = print_insn_mnem(xr); auto vtable_assign = (xr_mnem == "mov" || xr_mnem == "lea"); if (fstart != BADADDR && vtable_assign) { auto fend = get_func_attr(fstart, FUNCATTR_END); auto fsize = fend - fstart; auto rel = xr - fstart; auto early = (fsize > 0) && (rel < (fsize / 2 + 8) || rel < 64); if (early) { auto cur_name = get_func_name(fstart); auto auto_named = (cur_name == "" || starts_with(cur_name, "sub_")); auto is_dtor = is_destructor(fstart); if (is_dtor) { g_stat_dtors = g_stat_dtors + 1; if ((auto_named || RENAME_OVERRIDES) && !DRY_RUN) { auto dname; if (dtor_idx == 0) dname = sname_class + "__dtor"; else dname = sname_class + "__dtor_" + ltoa(dtor_idx, 10); set_name(fstart, dname, SN_NOWARN | SN_FORCE); set_color(fstart, CIC_FUNC, COLOR_DTOR); log_info(" [DTOR-renamed] " + dname + " @ 0x" + ltoa(fstart, 16)); } else { if (!DRY_RUN) set_color(fstart, CIC_FUNC, COLOR_DTOR); log_info(" [DTOR-detected] " + cur_name + " @ 0x" + ltoa(fstart, 16)); } dtor_idx = dtor_idx + 1; } else { g_stat_ctors = g_stat_ctors + 1; if ((auto_named || RENAME_OVERRIDES) && !DRY_RUN) { auto cname2; if (ctor_idx == 0) cname2 = sname_class + "__ctor"; else cname2 = sname_class + "__ctor_" + ltoa(ctor_idx, 10); set_name(fstart, cname2, SN_NOWARN | SN_FORCE); set_color(fstart, CIC_FUNC, COLOR_CTOR); log_info(" [CTOR-renamed] " + cname2 + " @ 0x" + ltoa(fstart, 16)); } else { if (!DRY_RUN) set_color(fstart, CIC_FUNC, COLOR_CTOR); log_info(" [CTOR-detected] " + cur_name + " @ 0x" + ltoa(fstart, 16)); } ctor_idx = ctor_idx + 1; if (first_ctor == BADADDR) first_ctor = fstart; } } } xr = get_next_dref_to(vtable_ea, xr); } if (first_ctor != BADADDR) { if (DETECT_OBJECT_SIZES) { auto size = find_object_size_for_ctor_v2(first_ctor); if (size > 0 && size < 0x10000) { arr_set_long(ARR_VT2SIZE, vtable_ea, size); if (!DRY_RUN) { set_cmt(vtable_ea, sprintf("vtable de %s sizeof=0x%X (%d bytes)", sname_class, size, size), 1); } g_stat_sizes = g_stat_sizes + 1; log_info(" [SIZE] sizeof(" + sname_class + ") = 0x" + ltoa(size, 16)); } } if (DETECT_SINGLETONS) { auto sgl = detect_singleton_for_ctor(first_ctor, sname_class); if (sgl == BADADDR) { sgl = detect_singleton_aggressive(first_ctor, sname_class); } if (sgl != BADADDR) { arr_set_long(ARR_VT2SINGLETON, vtable_ea, sgl); g_stat_singletons = g_stat_singletons + 1; log_info(" [SGTN] " + sname_class + " instance @ 0x" + ltoa(sgl, 16)); } } } } // ========================================================================= // TAMANHO DA VTABLE // ========================================================================= static is_another_vtable_starting_here(slot_ea) { auto xr = get_first_dref_to(slot_ea); while (xr != BADADDR) { auto sn = seg_name_of(xr); if (strstr(sn, ".rdata") != -1 || strstr(sn, ".data") != -1) return 1; xr = get_next_dref_to(slot_ea, xr); } return 0; } static vtable_size(vtable_ea) { auto count = 0; auto cur = vtable_ea; while (count < MAX_VTABLE_METHODS) { auto p = read_ptr(cur); if (!is_valid_code_ptr(p)) break; if (count > 0 && is_another_vtable_starting_here(cur)) break; count = count + 1; cur = cur + g_ptr_size; } return count; } // ========================================================================= // STRUCT DA VTABLE // ========================================================================= static create_vtable_struct(sname_class, vtable_ea, count) { if (!CREATE_STRUCTS) return; if (DRY_RUN) return; auto sname = "vtable_" + sname_class + "_t"; auto sid = get_struc_id(sname); if (sid != BADADDR) del_struc(sid); sid = add_struc(-1, sname, 0); if (sid == BADADDR) { log_warn(" Falha ao criar struct " + sname); return; } auto i; for (i = 0; i < count; i = i + 1) { auto slot = vtable_ea + (i * g_ptr_size); auto faddr = read_ptr(slot); auto fname = get_func_name(faddr); auto member; if (fname == 0 || fname == "" || starts_with(fname, "sub_")) { member = "vmethod_" + ltoa(i, 10); } else { auto pos = strstr(fname, "::"); if (pos != -1) member = substr(fname, pos + 2, strlen(fname)); else member = fname; member = sanitize_name(member); } auto base_member = member; auto suffix = 0; while (get_member_offset(sid, member) != -1 && suffix < 64) { suffix = suffix + 1; member = base_member + "_" + ltoa(suffix, 10); } auto flag = g_is_64 ? (FF_QWORD | FF_DATA) : (FF_DWORD | FF_DATA); add_struc_member(sid, member, i * g_ptr_size, flag, -1, g_ptr_size); } log_info(" [STRUCT] " + sname + " (" + ltoa(count, 10) + " slots)"); } // ========================================================================= // EMISSAO DE JSON (uma classe) // ========================================================================= // // FIX item 2: emit_parents_json itera direto sobre o CSV numerico de TDs, // sem nunca passar pela string "pretty" (que tinha ", " e quebrava com // templates demangled). // static emit_parents_json(jf, csv) { if (jf == 0 || csv == "" || csv == 0) return; auto buf = ""; auto first = 1; auto i; auto n = strlen(csv); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(csv, i, i + 1) : ","; if (c == ",") { if (buf != "") { auto td = atol(buf); auto mang = read_typedesc_name(td); auto nm = (mang != "") ? demangle_class_name(mang) : "??"; if (!first) fprintf(jf, ", "); fprintf(jf, "\"%s\"", json_escape(nm)); first = 0; } buf = ""; } else { buf = buf + c; } } } static emit_class_json(cname, sname, mangled, vt_ea, col_ea, count, parents_csv) { auto jf = g_json_handle; if (jf == 0) return; if (!g_json_first) fprintf(jf, ",\n"); g_json_first = 0; fprintf(jf, " {\n"); fprintf(jf, " \"class\": \"%s\",\n", json_escape(cname)); fprintf(jf, " \"sanitized\": \"%s\",\n", json_escape(sname)); fprintf(jf, " \"mangled\": \"%s\",\n", json_escape(mangled)); fprintf(jf, " \"vtable_ea\": \"0x%x\",\n", vt_ea); fprintf(jf, " \"col_ea\": \"0x%x\",\n", col_ea); fprintf(jf, " \"method_count\": %d,\n", count); fprintf(jf, " \"parents\": ["); emit_parents_json(jf, parents_csv); fprintf(jf, "],\n"); auto col_offset_v = arr_get_long(ARR_VT2OFFSET, vt_ea); if (col_offset_v == -1) col_offset_v = 0; if (col_offset_v != 0) { fprintf(jf, " \"is_secondary\": true,\n"); fprintf(jf, " \"sub_offset\": %d,\n", col_offset_v); } auto size_v = arr_get_long(ARR_VT2SIZE, vt_ea); auto sgl_v = arr_get_long(ARR_VT2SINGLETON, vt_ea); if (size_v > 0) fprintf(jf, " \"sizeof\": %d,\n", size_v); if (sgl_v != -1 && sgl_v != BADADDR) fprintf(jf, " \"singleton_ea\": \"0x%x\",\n", sgl_v); fprintf(jf, " \"methods\": [\n"); auto j; for (j = 0; j < count; j = j + 1) { auto slot = vt_ea + (j * g_ptr_size); auto faddr = read_ptr(slot); auto kind = "vmethod"; if (is_pure_call(faddr)) kind = "pure"; else if (j <= 1 && is_destructor(faddr)) kind = "deleting_dtor"; fprintf(jf, " {\"index\": %d, \"slot_ea\": \"0x%x\", \"func_ea\": \"0x%x\", \"name\": \"%s\", \"kind\": \"%s\"}", j, slot, faddr, json_escape(get_func_name(faddr)), kind); if (j < count - 1) fprintf(jf, ","); fprintf(jf, "\n"); } fprintf(jf, " ]\n"); fprintf(jf, " }"); } // ========================================================================= // v5.3: FILTRO DE FRAMEWORK CLASSES // Evita poluir o output com classes do MFC/STL/ATL que o usuario raramente // quer mexer. Identificacao por prefixo de nome. // ========================================================================= static is_framework_class(name) { if (name == 0 || name == "") return 0; if (starts_with(name, "std::")) return 1; if (starts_with(name, "ATL::")) return 1; if (starts_with(name, "Gdiplus::")) return 1; if (starts_with(name, "Json::")) return 1; if (starts_with(name, "CMFC")) return 1; if (starts_with(name, "CMap<")) return 1; if (starts_with(name, "CArray<")) return 1; if (starts_with(name, "CList<")) return 1; if (starts_with(name, "CTypedPtr")) return 1; if (starts_with(name, "CResourcePool<")) return 1; if (starts_with(name, "DataPool<")) return 1; if (starts_with(name, "COle")) return 1; if (starts_with(name, "CDoc")) return 1; if (starts_with(name, "CDock")) return 1; if (starts_with(name, "CWnd")) return 1; if (starts_with(name, "CWin")) return 1; if (starts_with(name, "CCmd")) return 1; if (starts_with(name, "_AFX")) return 1; if (starts_with(name, "AFX_")) return 1; if (strstr(name, "tpl_") != -1) return 1; if (name == "type_info") return 1; return 0; } // ========================================================================= // v5.3: SIZEOF DETECTOR v2 // Tenta multiplos padroes pra detectar sizeof do objeto: // 1. push imm + call new (padrao MSVC stdlib) // 2. mov ecx/edx, imm + call <custom_alloc> // 3. mov [esp], imm + call <alloc> // 4. (fallback) inferir pelo max offset escrito em [this+N] no body do ctor // ========================================================================= static find_object_size_v2_caller(call_ea) { auto fstart = get_func_attr(call_ea, FUNCATTR_START); if (fstart == BADADDR) fstart = call_ea - 0x80; auto cur = call_ea; auto guard = 0; while (guard < 20) { cur = prev_head(cur, fstart); if (cur == BADADDR || cur == 0 || cur < fstart) break; auto m = print_insn_mnem(cur); if (m == "ret" || m == "jmp") break; if (m == "call") { auto tgt = get_first_fcref_from(cur); if (tgt != BADADDR) { auto tn = get_func_name(tgt); if (tn != 0 && tn != "") { auto is_alloc = 0; if (strstr(tn, "operator new") != -1) is_alloc = 1; if (strstr(tn, "??2@") != -1) is_alloc = 1; if (strstr(tn, "_malloc") != -1) is_alloc = 1; if (tn == "malloc" || tn == "_malloc") is_alloc = 1; if (strstr(tn, "Alloc") != -1) is_alloc = 1; if (strstr(tn, "alloc") != -1) is_alloc = 1; if (strstr(tn, "MemNew") != -1) is_alloc = 1; if (is_alloc) { auto pcur = cur; auto pg = 0; while (pg < 8) { pcur = prev_head(pcur, fstart); if (pcur == BADADDR || pcur < fstart) break; auto pm = print_insn_mnem(pcur); if (pm == "push" && get_operand_type(pcur, 0) == o_imm) { return get_operand_value(pcur, 0); } if (pm == "mov" && get_operand_type(pcur, 0) == o_reg && get_operand_type(pcur, 1) == o_imm) { auto v = get_operand_value(pcur, 1); if (v > 0 && v < 0x10000) return v; } if (pm == "mov" && get_operand_type(pcur, 0) == o_displ && get_operand_type(pcur, 1) == o_imm) { auto v2 = get_operand_value(pcur, 1); if (v2 > 0 && v2 < 0x10000) return v2; } pg = pg + 1; } } } } return 0; } guard = guard + 1; } return 0; } static infer_size_from_ctor_body(ctor_ea) { if (!SIZE_INFER_FROM_BODY) return 0; auto fend = get_func_attr(ctor_ea, FUNCATTR_END); if (fend == BADADDR) return 0; if ((fend - ctor_ea) > 0x800) return 0; auto max_off = 0; auto ea = ctor_ea; auto guard = 0; while (ea < fend && ea != BADADDR && guard < SIZE_BODY_SCAN_LIMIT) { auto i; for (i = 0; i < 2; i = i + 1) { if (get_operand_type(ea, i) == o_displ) { auto disp = get_operand_value(ea, i); if (disp > max_off && disp < 0x10000) { auto op_str = print_operand(ea, i); if (strstr(op_str, "ecx") != -1 || strstr(op_str, "esi") != -1 || strstr(op_str, "edi") != -1 || strstr(op_str, "ebx") != -1) { max_off = disp; } } } } ea = next_head(ea, fend); guard = guard + 1; } if (max_off == 0) return 0; return max_off + g_ptr_size; } static find_object_size_for_ctor_v2(ctor_ea) { auto xr = get_first_cref_to(ctor_ea); while (xr != BADADDR) { auto sz = find_object_size_v2_caller(xr); if (sz > 0 && sz < 0x10000) return sz; xr = get_next_cref_to(ctor_ea, xr); } auto body_sz = infer_size_from_ctor_body(ctor_ea); if (body_sz > 0) return body_sz; return 0; } // ========================================================================= // v5.3: SINGLETON DETECTOR v2 (mais agressivo) // Alem de "mov ds:G, eax" pos-ctor, detecta: // - Funcao curta que retorna sempre o mesmo global ("GetInstance" pattern) // - Lazy init pattern: "if (!g_X) g_X = new X(); return g_X;" // ========================================================================= static detect_singleton_aggressive(ctor_ea, class_name) { if (!SINGLETON_AGGRESSIVE) return BADADDR; auto xr = get_first_cref_to(ctor_ea); while (xr != BADADDR) { auto caller_start = get_func_attr(xr, FUNCATTR_START); if (caller_start == BADADDR) { xr = get_next_cref_to(ctor_ea, xr); continue; } auto caller_end = get_func_attr(caller_start, FUNCATTR_END); auto caller_size = caller_end - caller_start; if (caller_size > 0 && caller_size < 0x100) { auto cur = caller_start; auto g = 0; while (cur < caller_end && cur != BADADDR && g < 30) { auto m = print_insn_mnem(cur); if (m == "mov" && get_operand_type(cur, 0) == o_reg && get_operand_type(cur, 1) == o_mem) { auto g_ea = get_operand_value(cur, 1); if (is_loaded(g_ea) && g_ea > 0x1000) { auto cn = get_func_name(caller_start); if (cn != "" && (strstr(cn, "etInstance") != -1 || strstr(cn, "etSingleton") != -1 || strstr(cn, "_instance") != -1 || caller_size < 0x40)) { mark_singleton(g_ea, class_name, ctor_ea); return g_ea; } } } cur = next_head(cur, caller_end); g = g + 1; } } xr = get_next_cref_to(ctor_ea, xr); } return BADADDR; } // ========================================================================= // ANALISE DE UMA VTABLE // ========================================================================= static analyze_vtable(ea) { if (cache_seen(ea)) return 0; auto first_ptr = read_ptr(ea); if (!is_valid_code_ptr(first_ptr)) return 0; auto col_ea = read_ptr(ea - g_ptr_size); if (!validate_col(col_ea)) return 0; auto type_desc = col_read_field(col_ea, 0x0C); auto mangled = read_typedesc_name(type_desc); if (mangled == "") return 0; auto cname = demangle_class_name(mangled); if (cname == "") return 0; if (EXCLUDE_FRAMEWORK_CLASSES && is_framework_class(cname)) { g_stat_filtered = g_stat_filtered + 1; cache_mark(ea); return 0; } auto col_offset = get_wide_dword(col_ea + 0x04); auto sname = sanitize_name(cname); auto display_name = cname; if (col_offset != 0) { sname = sname + "_sub_" + ltoa(col_offset, 16); display_name = cname + " [secondary @ +0x" + ltoa(col_offset, 16) + "]"; } auto count = vtable_size(ea); if (count < MIN_VTABLE_METHODS) return 0; auto parents_csv = parse_base_classes(col_ea); auto parents_pretty; if (col_offset != 0) { auto ptd = find_parent_td_for_offset(col_ea, col_offset); if (ptd != 0) { auto pmang = read_typedesc_name(ptd); parents_pretty = (pmang != "") ? demangle_class_name(pmang) : "??"; } else { parents_pretty = ""; } } else { parents_pretty = parents_csv_to_names(parents_csv); } log_info("Classe: " + display_name + " (" + ltoa(count, 10) + " metodos) vtable=0x" + ltoa(ea, 16) + " COL=0x" + ltoa(col_ea, 16)); log_info(" mangled = " + mangled); if (parents_pretty != "") { if (col_offset != 0) log_info(" base = " + parents_pretty); else log_info(" pais = " + parents_pretty); } g_stat_classes = g_stat_classes + 1; g_stat_methods = g_stat_methods + count; if (!DRY_RUN) { set_name(ea, "vtable_" + sname, SN_NOWARN | SN_FORCE); set_name(col_ea, "RTTI_COL_" + sname, SN_NOWARN | SN_FORCE); set_color(col_ea, CIC_ITEM, COLOR_RTTI_COL); set_cmt(col_ea, "CompleteObjectLocator de " + cname + (col_offset != 0 ? sprintf(" (offset 0x%X)", col_offset) : ""), 1); if (col_offset == 0) { set_name(type_desc, "RTTI_TD_" + sname, SN_NOWARN | SN_FORCE); set_color(type_desc, CIC_ITEM, COLOR_TYPE_DESC); set_cmt(type_desc, "TypeDescriptor de " + cname, 1); } if (col_offset != 0) { set_cmt(ea, "vtable secundaria de " + cname + " base " + (parents_pretty != "" ? parents_pretty : "??") + " @ offset 0x" + ltoa(col_offset, 16), 1); } else if (parents_pretty != "") { set_cmt(ea, "vtable de " + cname + " herda de: " + parents_pretty, 1); } else { set_cmt(ea, "vtable de " + cname, 1); } } auto i; for (i = 0; i < count; i = i + 1) { auto slot = ea + (i * g_ptr_size); auto faddr = read_ptr(slot); auto vname; auto vcolor = COLOR_VFUNC; if (is_pure_call(faddr)) { vname = sname + "__pure_v" + ltoa(i, 10); vcolor = COLOR_PURE; g_stat_pures = g_stat_pures + 1; } else if (i <= 1 && is_destructor(faddr)) { vname = sname + "__deleting_dtor_v" + ltoa(i, 10); vcolor = COLOR_DTOR; } else { vname = sname + "__vmethod_" + ltoa(i, 10); } auto cur_name = get_func_name(faddr); auto can_rename = (cur_name == "" || starts_with(cur_name, "sub_") || RENAME_OVERRIDES); if (!DRY_RUN && can_rename) { if (set_name(faddr, vname, SN_NOWARN | SN_FORCE)) { g_stat_renamed = g_stat_renamed + 1; } } if (!DRY_RUN) { set_color(slot, CIC_ITEM, COLOR_VTABLE_SLOT); set_color(faddr, CIC_FUNC, vcolor); set_cmt(slot, sprintf("[%d] +0x%X -> %s", i, i * g_ptr_size, vname), 0); } } create_vtable_struct(sname, ea, count); if (col_offset == 0) rename_constructors(ea, sname); hier_register(type_desc, ea, col_ea, sname, count, parents_csv, col_offset); emit_class_json(display_name, sname, mangled, ea, col_ea, count, parents_csv); cache_mark(ea); return count; } // ========================================================================= // STRING-FIRST: helpers // ========================================================================= // v5.2 DEBUG: loga em detalhe cada xref do TD e o resultado da validacao // pra entender por que estamos perdendo as vtables. static validate_col_verbose(col_ea) { if (!is_valid_data_ptr(col_ea)) { msg(" [reject] data_ptr invalido\n"); return 0; } auto sig = get_wide_dword(col_ea); auto expected = g_is_64 ? 1 : 0; if (sig != expected) { msg(" [reject] sig=0x%x esperado=%d\n", sig, expected); return 0; } auto offset = get_wide_dword(col_ea + 0x04); auto cdOffset = get_wide_dword(col_ea + 0x08); if (offset > 0x10000) { msg(" [reject] offset=0x%x grande demais\n", offset); return 0; } if (cdOffset > 0x10000) { msg(" [reject] cdOffset=0x%x grande demais\n", cdOffset); return 0; } auto type_desc = col_read_field(col_ea, 0x0C); if (!is_valid_data_ptr(type_desc)) { msg(" [reject] type_desc=0x%x invalido\n", type_desc); return 0; } auto chd = col_read_field(col_ea, 0x10); if (!is_valid_data_ptr(chd)) { msg(" [reject] chd=0x%x invalido\n", chd); return 0; } auto chd_sig = get_wide_dword(chd); if (chd_sig != 0) { msg(" [reject] chd_sig=0x%x (esperado 0)\n", chd_sig); return 0; } auto nb = get_wide_dword(chd + 0x08); if (nb == 0 || nb > 256) { msg(" [reject] num_bases=%d\n", nb); return 0; } if (g_is_64) { auto self_rva = get_wide_dword(col_ea + 0x14); if (rva_to_ea(self_rva) != col_ea) { msg(" [reject] pSelf nao bate\n"); return 0; } } msg(" [accept] COL valido!\n"); return 1; } static process_typedesc_xrefs(td_ea) { auto found = 0; auto xr = get_first_dref_to(td_ea); while (xr != BADADDR) { auto col_candidate = xr - 0x0C; if (validate_col(col_candidate)) { auto xv = get_first_dref_to(col_candidate); while (xv != BADADDR) { auto vtable_candidate = xv + g_ptr_size; if (is_valid_code_ptr(read_ptr(vtable_candidate))) { if (analyze_vtable(vtable_candidate) > 0) found = found + 1; } xv = get_next_dref_to(col_candidate, xv); } } xr = get_next_dref_to(td_ea, xr); } return found; } static byte_at(ea) { return get_wide_byte(ea); } static scan_via_rtti_strings() { log_info("=== Modo string-first ==="); auto total = 0; auto strings_found = 0; auto iters = 0; auto seg; for (seg = get_first_seg(); seg != BADADDR; seg = get_next_seg(seg)) { auto sn = get_segm_name(seg); if (strstr(sn, ".rdata") == -1 && strstr(sn, ".data") == -1) continue; auto ss = get_segm_start(seg); auto se = get_segm_end(seg); if (STRING_SCAN_MAX_SEG_SIZE > 0 && (se - ss) > STRING_SCAN_MAX_SEG_SIZE) { log_warn("Pulando " + sn + " (tamanho " + ltoa(se - ss, 16) + " > limite " + ltoa(STRING_SCAN_MAX_SEG_SIZE, 16) + ")"); continue; } log_info("Procurando .?AV/.?AU em " + sn + " [0x" + ltoa(ss, 16) + " - 0x" + ltoa(se, 16) + "]"); auto ea = ss; while (ea < se - 8) { if (user_cancelled()) return total; iters = iters + 1; if ((iters % (PROGRESS_EVERY * 4)) == 0) { msg("[string-scan] 0x%x | strings: %d | classes: %d\n", ea, strings_found, g_stat_classes); } if (byte_at(ea) == 0x2E && byte_at(ea + 1) == 0x3F && byte_at(ea + 2) == 0x41 && (byte_at(ea + 3) == 0x56 || byte_at(ea + 3) == 0x55)) { auto mangled = read_c_string_raw(ea); if (mangled != 0 && mangled != "" && ends_with(mangled, "@@")) { strings_found = strings_found + 1; auto td_ea = ea - (g_ptr_size * 2); if (is_valid_data_ptr(td_ea)) { total = total + process_typedesc_xrefs(td_ea); } auto sl = strlen(mangled); ea = ea + sl + 1; } else { ea = ea + 1; } } else { ea = ea + 1; } } } log_info("string-first: " + ltoa(strings_found, 10) + " strings RTTI vistas, " + ltoa(total, 10) + " novas vtables analisadas"); return total; } // ========================================================================= // PONTEIRO-SEQUENCIAL // ========================================================================= static scan_via_pointers() { log_info("=== Modo ponteiro-sequencial ==="); auto total = 0; auto iters = 0; auto seg; for (seg = get_first_seg(); seg != BADADDR; seg = get_next_seg(seg)) { auto sn = get_segm_name(seg); auto match = (strstr(sn, ".rdata") != -1); if (SCAN_DATA_TOO && strstr(sn, ".data") != -1 && strstr(sn, ".rdata") == -1) match = 1; if (!match) continue; auto ss = get_segm_start(seg); auto se = get_segm_end(seg); log_info("Varrendo " + sn + " [0x" + ltoa(ss, 16) + " - 0x" + ltoa(se, 16) + "]"); auto ea = ss; while (ea < se) { if (user_cancelled()) return total; iters = iters + 1; if ((iters % PROGRESS_EVERY) == 0) { msg("[ponteiro-scan] 0x%x | classes: %d | metodos: %d\n", ea, g_stat_classes, g_stat_methods); } auto consumed = analyze_vtable(ea); if (consumed > 0) { total = total + 1; ea = ea + (consumed * g_ptr_size); } else { ea = ea + g_ptr_size; } } } log_info("ponteiro-scan: " + ltoa(total, 10) + " vtables analisadas"); return total; } // ========================================================================= // BRUTE-FORCE RTTI (x64 e x86) - fallback quando IDA nao tracou xrefs // // Estrategia identica em ambas arquiteturas, apenas a assinatura do COL // e o tamanho do ponteiro mudam: // // 1) varremos .rdata em alinhamento 4 procurando COL candidatos: // x64: signature == 1 e pSelf RVA consistente // x86: signature == 0 e validate_col passa // 2) para cada COL valido, tentamos xrefs; se nao houver, fazemos // um segundo scan procurando ptrs (qword em x64, dword em x86) // que apontam pro COL - isso eh vtable[-1]. // // ========================================================================= static align_up_4(ea) { auto rem = ea - ((ea / 4) * 4); if (rem == 0) return ea; return ea + (4 - rem); } static align_up_8(ea) { auto rem = ea - ((ea / 8) * 8); if (rem == 0) return ea; return ea + (8 - rem); } static brute_force_vt_for_col(col_ea) { auto found = 0; auto seg; for (seg = get_first_seg(); seg != BADADDR; seg = get_next_seg(seg)) { auto sn = get_segm_name(seg); if (strstr(sn, ".rdata") == -1) continue; auto ss = get_segm_start(seg); auto se = get_segm_end(seg); auto ea = g_is_64 ? align_up_8(ss) : align_up_4(ss); while (ea < se - g_ptr_size * 2) { if (user_cancelled()) return found; auto cur_val = read_ptr(ea); if (cur_val == col_ea) { auto vt = ea + g_ptr_size; if (is_valid_code_ptr(read_ptr(vt))) { if (analyze_vtable(vt) > 0) found = found + 1; } } ea = ea + g_ptr_size; } } return found; } static brute_force_rtti() { if (g_is_64) { if (!BRUTE_FORCE_X64_RVA) return 0; } else { if (!BRUTE_FORCE_X86) return 0; } auto expected_sig = g_is_64 ? 1 : 0; auto arch_label = g_is_64 ? "x64" : "x86"; log_info("=== Brute-force " + arch_label + " (COL signature=" + ltoa(expected_sig, 10) + ") ==="); auto found = 0; auto iters = 0; auto seg; for (seg = get_first_seg(); seg != BADADDR; seg = get_next_seg(seg)) { if (user_cancelled()) return found; auto sn = get_segm_name(seg); if (strstr(sn, ".rdata") == -1) continue; auto ss = get_segm_start(seg); auto se = get_segm_end(seg); log_info("Brute-scan em " + sn + " [0x" + ltoa(ss, 16) + " - 0x" + ltoa(se, 16) + "]"); auto ea = align_up_4(ss); while (ea < se - 24) { if (user_cancelled()) return found; iters = iters + 1; if ((iters % PROGRESS_EVERY) == 0) { msg("[brute-scan] 0x%x | achadas: %d\n", ea, g_stat_brute); } if (get_wide_dword(ea) == expected_sig) { auto cheap_ok = 1; if (g_is_64) { auto self_rva = get_wide_dword(ea + 0x14); if (rva_to_ea(self_rva) != ea) cheap_ok = 0; } if (cheap_ok && validate_col(ea)) { auto vt_found = 0; auto xv = get_first_dref_to(ea); while (xv != BADADDR) { auto vt = xv + g_ptr_size; if (is_valid_code_ptr(read_ptr(vt))) { if (analyze_vtable(vt) > 0) { vt_found = vt_found + 1; found = found + 1; g_stat_brute = g_stat_brute + 1; } } xv = get_next_dref_to(ea, xv); } if (vt_found == 0) { auto extra = brute_force_vt_for_col(ea); found = found + extra; g_stat_brute = g_stat_brute + extra; } } } ea = ea + 4; if ((ea & 0xFFFF) == 0) { } } } log_info("brute " + arch_label + ": " + ltoa(found, 10) + " novas vtables"); return found; } static brute_force_x64() { return brute_force_rtti(); } // ========================================================================= // PROPAGACAO DE OVERRIDES // // Para cada classe com pais, percorre o primeiro pai (ancestral imediato) // e compara slot a slot: // - Mesmo func ptr -> METODO HERDADO (apenas registra) // - Func ptr difere -> OVERRIDE (comenta no slot e na funcao) // // Tambem emite vtables_overrides.json com as relacoes encontradas. // ========================================================================= static emit_override_json(child_name, child_vt, slot_idx, parent_name, parent_func, child_func) { auto of = g_overrides_handle; if (of == 0) return; if (!g_overrides_first) fprintf(of, ",\n"); g_overrides_first = 0; fprintf(of, " {\"child\": \"%s\", \"slot\": %d, \"parent\": \"%s\", \"parent_func\": \"0x%x\", \"child_func\": \"0x%x\"}", child_name, slot_idx, parent_name, parent_func, child_func); } static first_parent_td(parents_csv) { if (parents_csv == "" || parents_csv == 0) return 0; auto pos = strstr(parents_csv, ","); auto first = (pos != -1) ? substr(parents_csv, 0, pos) : parents_csv; return atol(first); } static find_parent_td_for_offset(col_ea, target_offset) { if (target_offset == 0) return 0; auto chd = col_read_field(col_ea, 0x10); if (!is_valid_data_ptr(chd)) return 0; auto num_bases = get_wide_dword(chd + 0x08); if (num_bases <= 1 || num_bases > 64) return 0; auto bca_field = get_wide_dword(chd + 0x0C); auto bca_ea = g_is_64 ? rva_to_ea(bca_field) : bca_field; if (!is_valid_data_ptr(bca_ea)) return 0; auto i; for (i = 1; i < num_bases; i = i + 1) { auto bcd_field = get_wide_dword(bca_ea + i * 4); auto bcd_ea = g_is_64 ? rva_to_ea(bcd_field) : bcd_field; if (!is_valid_data_ptr(bcd_ea)) continue; auto mdisp = get_wide_dword(bcd_ea + 0x08); if (mdisp == target_offset) { auto td_field = get_wide_dword(bcd_ea); return g_is_64 ? rva_to_ea(td_field) : td_field; } } return 0; } // ========================================================================= // TOPOLOGICAL SORT (pais antes de filhos) // ========================================================================= static topo_dfs(vt_ea, count) { if (arr_get_long(ARR_TOPO_VISITED, vt_ea) > 0) return count; arr_set_long(ARR_TOPO_VISITED, vt_ea, 1); auto parents = hier_parents(vt_ea); auto buf = ""; auto i; auto n = strlen(parents); for (i = 0; i <= n; i = i + 1) { auto c = (i < n) ? substr(parents, i, i + 1) : ","; if (c == ",") { if (buf != "") { auto td = atol(buf); auto pvt = hier_vt_by_td(td); if (pvt != BADADDR) count = topo_dfs(pvt, count); } buf = ""; } else { buf = buf + c; } } arr_set_long(ARR_TOPO_ORDER, count, vt_ea); return count + 1; } static topo_build() { arr_init(ARR_TOPO_VISITED); arr_init(ARR_TOPO_ORDER); arr_init(ARR_TOPO_COUNT); auto count = 0; auto i; for (i = 0; i < g_vt_list_count; i = i + 1) { if (user_cancelled()) break; auto vt = hier_vt_at(i); if (vt != BADADDR) count = topo_dfs(vt, count); } arr_set_long(ARR_TOPO_COUNT, 0, count); log_info("Topological order: " + ltoa(count, 10) + " classes"); return count; } static topo_at(idx) { auto v = arr_get_long(ARR_TOPO_ORDER, idx); if (v == -1) return BADADDR; return v; } static topo_count() { auto v = arr_get_long(ARR_TOPO_COUNT, 0); if (v == -1) return 0; return v; } static propagate_overrides() { if (!PROPAGATE_OVERRIDES) return; if (g_vt_list_count == 0) return; auto tcount = topo_count(); if (tcount == 0) return; log_info("=== Passada de overrides em ordem topologica (" + ltoa(tcount, 10) + " classes) ==="); auto i; for (i = 0; i < tcount; i = i + 1) { if (user_cancelled()) return; auto vt_ea = topo_at(i); if (vt_ea == BADADDR) continue; auto parents_csv = hier_parents(vt_ea); if (parents_csv == "") continue; auto col_offset = hier_offset(vt_ea); auto parent_td; if (col_offset == 0) { parent_td = first_parent_td(parents_csv); } else { auto col_ea2 = hier_col(vt_ea); if (col_ea2 == BADADDR) continue; parent_td = find_parent_td_for_offset(col_ea2, col_offset); } if (parent_td == 0) continue; auto parent_vt = hier_vt_by_td(parent_td); if (parent_vt == BADADDR) { continue; } auto child_name = hier_name(vt_ea); auto parent_name = hier_name(parent_vt); auto own_count = hier_count(vt_ea); auto parent_count = hier_count(parent_vt); auto limit = (parent_count < own_count) ? parent_count : own_count; auto j; for (j = 0; j < limit; j = j + 1) { auto cslot = vt_ea + j * g_ptr_size; auto pslot = parent_vt + j * g_ptr_size; auto cfunc = read_ptr(cslot); auto pfunc = read_ptr(pslot); if (cfunc == pfunc) { g_stat_inherited = g_stat_inherited + 1; if (!DRY_RUN) { auto pname = get_func_name(pfunc); auto child_pattern = child_name + "__vmethod_" + ltoa(j, 10); if (pname == child_pattern) { auto canonical = parent_name + "__vmethod_" + ltoa(j, 10); if (set_name(pfunc, canonical, SN_NOWARN | SN_FORCE)) { g_stat_renamed_inherited = g_stat_renamed_inherited + 1; pname = canonical; } } set_cmt(cslot, sprintf("[%d] HERDADO de %s (-> %s)", j, parent_name, pname), 0); } } else { g_stat_overrides = g_stat_overrides + 1; if (!DRY_RUN) { auto pname2 = get_func_name(pfunc); set_cmt(cslot, sprintf("[%d] OVERRIDE de %s::%s", j, parent_name, pname2), 0); set_color(cslot, CIC_ITEM, COLOR_OVERRIDE); auto cfn = get_func_name(cfunc); auto rep = "Override de " + parent_name + "::" + pname2; auto existing = get_func_cmt(cfunc, 1); auto can_set_func_cmt = 0; if (existing == "" || existing == 0) can_set_func_cmt = 1; else if (starts_with(existing, "Override de ")) can_set_func_cmt = 1; if (can_set_func_cmt) set_func_cmt(cfunc, rep, 1); } emit_override_json(child_name, vt_ea, j, parent_name, pfunc, cfunc); } } } log_info("Overrides: " + ltoa(g_stat_overrides, 10) + " Herdados: " + ltoa(g_stat_inherited, 10)); } // ========================================================================= // MAIN // ========================================================================= static main() { if (CLEAR_OUTPUT_ON_START) { process_ui_action("msglist:Clear", 0); } msg("\n========================================\n"); msg("Vtable Analyzer Pro v5.3 - iniciando...\n"); msg("========================================\n"); if (REGISTER_HOTKEY) { add_idc_hotkey(HOTKEY_COMBO, "main"); msg("[INFO] Hotkey %s registrada para re-rodar o script\n", HOTKEY_COMBO); } g_is_64 = (get_inf_attr(INF_LFLAGS) & LFLG_64BIT) ? 1 : 0; g_ptr_size = g_is_64 ? 8 : 4; g_imagebase = get_imagebase(); g_json_first = 1; g_overrides_first = 1; g_vt_list_count = 0; g_stat_classes = 0; g_stat_methods = 0; g_stat_renamed = 0; g_stat_ctors = 0; g_stat_dtors = 0; g_stat_pures = 0; g_stat_overrides = 0; g_stat_inherited = 0; g_stat_brute = 0; g_stat_thiscall = 0; g_stat_sizes = 0; g_stat_singletons = 0; g_stat_vcalls = 0; g_stat_header_classes = 0; g_stat_renamed_inherited = 0; g_purecall_csv = ""; g_stat_filtered = 0; g_stat_errors = 0; auto out_dir = resolve_output_dir(); auto json_path = path_join(out_dir, OUTPUT_JSON_NAME); auto log_path = path_join(out_dir, OUTPUT_LOG_NAME); auto overrides_path = path_join(out_dir, OUTPUT_OVERRIDES_NAME); auto header_path = path_join(out_dir, OUTPUT_HEADER_NAME); msg("[INFO] Pasta de saida: %s\n", out_dir); msg("[INFO] JSON esperado em: %s\n", json_path); msg("[INFO] LOG esperado em: %s\n", log_path); msg("[INFO] OVERRIDES esperado em: %s\n", overrides_path); msg("[INFO] HEADER esperado em: %s\n", header_path); g_log_handle = safe_fopen(log_path, "w"); if (g_log_handle == 0) { msg("[WARN] Log em arquivo desabilitado, continuando so com console.\n"); } log_info("===================================================="); log_info(" Vtable Analyzer Pro v5.3 - IDA Free 9.x"); log_info("===================================================="); log_info("Arquitetura : " + (g_is_64 ? "x64" : "x86")); log_info("Ptr size : " + ltoa(g_ptr_size, 10)); log_info("Image base : 0x" + ltoa(g_imagebase, 16)); log_info("Pasta saida : " + out_dir); log_info("Dry run : " + (DRY_RUN ? "SIM" : "NAO")); log_info("Cria struct : " + (CREATE_STRUCTS ? "SIM" : "NAO")); log_info("Sobrescreve : " + (RENAME_OVERRIDES ? "SIM" : "NAO")); log_info("Ponteiro-scan: " + (POINTER_FIRST_SCAN ? "SIM" : "NAO")); log_info("String-scan : " + (STRING_FIRST_SCAN ? "SIM" : "NAO")); log_info("Overrides : " + (PROPAGATE_OVERRIDES ? "SIM" : "NAO")); log_info("Brute x64 : " + (BRUTE_FORCE_X64_RVA ? "SIM" : "NAO") + (g_is_64 ? "" : " (inerte em x86)")); log_info("Brute x86 : " + (BRUTE_FORCE_X86 ? "SIM" : "NAO") + (g_is_64 ? " (inerte em x64)" : "")); log_info("__thiscall : " + (APPLY_THISCALL_TYPES ? "SIM" : "NAO")); log_info("Sizeof obj : " + (DETECT_OBJECT_SIZES ? "SIM" : "NAO")); log_info("Singletons : " + (DETECT_SINGLETONS ? "SIM" : "NAO")); log_info("VCall annotat: " + (ANNOTATE_VCALLS ? "SIM" : "NAO")); log_info("CPP header : " + (EMIT_CPP_HEADER ? "SIM" : "NAO")); log_info("Excl framewrk: " + (EXCLUDE_FRAMEWORK_CLASSES ? "SIM" : "NAO")); log_info("Size inferenc: " + (SIZE_INFER_FROM_BODY ? "SIM" : "NAO")); log_info("Singl agressv: " + (SINGLETON_AGGRESSIVE ? "SIM" : "NAO")); cache_init(); init_purecall_addresses(); if (g_purecall_csv != "") { log_info("purecall enderecos conhecidos: " + g_purecall_csv); } g_json_handle = safe_fopen(json_path, "w"); if (g_json_handle != 0) { fprintf(g_json_handle, "{\n"); fprintf(g_json_handle, " \"meta\": {\n"); fprintf(g_json_handle, " \"arch\": \"%s\",\n", g_is_64 ? "x64" : "x86"); fprintf(g_json_handle, " \"ptr_size\": %d,\n", g_ptr_size); fprintf(g_json_handle, " \"imagebase\": \"0x%x\",\n", g_imagebase); fprintf(g_json_handle, " \"tool\": \"vtable_analyzer_pro_v5.2\",\n"); fprintf(g_json_handle, " \"stats_note\": \"methods=total slots; pures/inherited/overrides sao subconjuntos disjuntos de methods\"\n"); fprintf(g_json_handle, " },\n"); fprintf(g_json_handle, " \"classes\": [\n"); } g_overrides_handle = safe_fopen(overrides_path, "w"); if (g_overrides_handle != 0) { fprintf(g_overrides_handle, "{\n \"overrides\": [\n"); } if (POINTER_FIRST_SCAN) scan_via_pointers(); if (STRING_FIRST_SCAN) scan_via_rtti_strings(); if ((g_is_64 && BRUTE_FORCE_X64_RVA) || (!g_is_64 && BRUTE_FORCE_X86)) brute_force_rtti(); topo_build(); propagate_overrides(); apply_all_thiscall_types(); annotate_virtual_calls(); emit_cpp_header(header_path); if (g_json_handle != 0) { fprintf(g_json_handle, "\n ],\n"); fprintf(g_json_handle, " \"stats\": {\n"); fprintf(g_json_handle, " \"classes\": %d,\n", g_stat_classes); fprintf(g_json_handle, " \"methods\": %d,\n", g_stat_methods); fprintf(g_json_handle, " \"renamed\": %d,\n", g_stat_renamed); fprintf(g_json_handle, " \"ctors\": %d,\n", g_stat_ctors); fprintf(g_json_handle, " \"dtors\": %d,\n", g_stat_dtors); fprintf(g_json_handle, " \"pures\": %d,\n", g_stat_pures); fprintf(g_json_handle, " \"overrides\": %d,\n", g_stat_overrides); fprintf(g_json_handle, " \"inherited\": %d,\n", g_stat_inherited); fprintf(g_json_handle, " \"brute_x64\": %d,\n", g_stat_brute); fprintf(g_json_handle, " \"thiscall\": %d,\n", g_stat_thiscall); fprintf(g_json_handle, " \"sizes\": %d,\n", g_stat_sizes); fprintf(g_json_handle, " \"singletons\":%d,\n", g_stat_singletons); fprintf(g_json_handle, " \"vcalls\": %d,\n", g_stat_vcalls); fprintf(g_json_handle, " \"hdr_class\": %d,\n", g_stat_header_classes); fprintf(g_json_handle, " \"renamed_inherited\": %d,\n", g_stat_renamed_inherited); fprintf(g_json_handle, " \"methods_concrete\": %d,\n", g_stat_methods - g_stat_pures); fprintf(g_json_handle, " \"filtered\": %d,\n", g_stat_filtered); fprintf(g_json_handle, " \"errors\": %d\n", g_stat_errors); fprintf(g_json_handle, " }\n}\n"); fclose(g_json_handle); } if (g_overrides_handle != 0) { fprintf(g_overrides_handle, "\n ]\n}\n"); fclose(g_overrides_handle); } log_info("===================================================="); log_info(" RESUMO"); log_info(" Classes encontradas : " + ltoa(g_stat_classes, 10)); log_info(" Metodos virtuais : " + ltoa(g_stat_methods, 10)); log_info(" Funcoes renomeadas : " + ltoa(g_stat_renamed, 10)); log_info(" Construtores : " + ltoa(g_stat_ctors, 10)); log_info(" Destrutores : " + ltoa(g_stat_dtors, 10)); log_info(" Purecalls : " + ltoa(g_stat_pures, 10)); log_info(" Overrides marcados : " + ltoa(g_stat_overrides, 10)); log_info(" Metodos herdados : " + ltoa(g_stat_inherited, 10)); log_info(" Brute x64 : " + ltoa(g_stat_brute, 10)); log_info(" __thiscall : " + ltoa(g_stat_thiscall, 10)); log_info(" Sizes detectados : " + ltoa(g_stat_sizes, 10)); log_info(" Singletons : " + ltoa(g_stat_singletons, 10)); log_info(" VCall sites : " + ltoa(g_stat_vcalls, 10)); log_info(" Classes no header : " + ltoa(g_stat_header_classes, 10)); log_info(" Renorm. herdados : " + ltoa(g_stat_renamed_inherited, 10)); log_info(" Metodos concretos : " + ltoa(g_stat_methods - g_stat_pures, 10)); log_info(" Filtradas (framework): " + ltoa(g_stat_filtered, 10)); log_info(" Erros : " + ltoa(g_stat_errors, 10)); log_info("===================================================="); log_info("JSON : " + json_path); log_info("OVERRIDES : " + overrides_path); log_info("HEADER : " + header_path); log_info("LOG : " + log_path); log_info(""); log_info("=== ARQUIVOS GERADOS ==="); auto check_h; check_h = fopen(json_path, "r"); if (check_h != 0) { fseek(check_h, 0, 2); log_info(sprintf(" JSON : %d bytes", ftell(check_h))); fclose(check_h); } else { log_info(" JSON : NAO GERADO"); } check_h = fopen(overrides_path, "r"); if (check_h != 0) { fseek(check_h, 0, 2); log_info(sprintf(" OVERRIDES : %d bytes", ftell(check_h))); fclose(check_h); } else { log_info(" OVERRIDES : NAO GERADO"); } check_h = fopen(header_path, "r"); if (check_h != 0) { fseek(check_h, 0, 2); log_info(sprintf(" HEADER : %d bytes", ftell(check_h))); fclose(check_h); } else { log_info(" HEADER : NAO GERADO"); } if (g_log_handle != 0) fclose(g_log_handle); msg("\n=== Vtable Analyzer Pro v5.3 finalizado ===\n"); msg("Classes=%d Metodos=%d Renomeadas=%d Ctors=%d Dtors=%d Pures=%d Overrides=%d\n", g_stat_classes, g_stat_methods, g_stat_renamed, g_stat_ctors, g_stat_dtors, g_stat_pures, g_stat_overrides); msg("ThisCall=%d Sizes=%d Singletons=%d VCalls=%d HdrClasses=%d\n", g_stat_thiscall, g_stat_sizes, g_stat_singletons, g_stat_vcalls, g_stat_header_classes); }1 ponto
-
Basta deslizar e assistir o quanto quiser de vídeos +18 curtos e longos! [hide][Hidden Content]] Basta clicar na opção do Tiktok e aproveitar os milhares de vídeos!1 ponto
-
MEUS CANAIS DE VÍDEOS HC CURSOS E TUTORIAIS 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️ VEICARECA GAMES 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️1 ponto
-
@ Grego Comprei uma conta disney em [Hidden Content] por conta deste post, e agora fica pedindo o código para confirmar a tela ou se estou fora de casa, já tem uma semana suporte n responde, nem email, nem whatsapp, usei o serviço apenas uma vez... Não recomendo. [edit] Comentei no discord da wc falando do problema, e me fizeram o reembolso.1 ponto
-
Fala, pessoal. Queria compartilhar com vocês esse repositório do WYD FieldScene Studio Pro. Mesmo não sendo programador, o trabalho do Hamilton me inspirou bastante. A base do projeto e toda a ideia inicial me chamaram atenção justamente pelo quanto essa ferramenta veio pra ajudar quem mexe com interface e edição de painéis no WYD. Sem exagero algum, eu cheguei em 90 versoes em testes "ta comm tempo né" kkk A partir disso, tive a ideia de tentar tornar o programa mais acessível, principalmente para quem não tem monitor com resolução muito alta ou acaba sofrendo com a limitação de espaço na tela durante a edição. Além disso, fui buscando implementar melhorias de usabilidade, organização visual e praticidade no fluxo de trabalho, sempre tentando deixar a ferramenta mais confortável e funcional no uso do dia a dia. O objetivo não foi apagar a origem do projeto, mas sim evoluir em cima de uma base que já era boa, trazendo adaptações, correções e recursos que pudessem facilitar a vida de mais pessoas. Entre os pontos que busquei melhorar estão: - melhor adaptação para diferentes resoluções - visualização em escala 1:1 - conversão e ajuste entre resoluções - carregamento e compatibilidade de recursos - melhorias no uso geral do editor - remoção de fundo em imagens compatíveis - mais praticidade para edição, importação e visualização -o programa tem régua -arraste por mouse **OBS IMPORTANTE, É RECOMENDADO QUE QUANDO FOR SOLICITADO O CARREGAMENTO DE RECURSOS ABRA ATÉ A PASTA DO CLIENTE ONDE ESTÃO AS PASTAS UI, NUI E MESH, ASSIM O PROGRRAMA JÁ CARREGA AS 3 PASTAS NO LUGGAR DE ABRIR UMA POR VEZ, ALGUNS PAINEIS AS VEZES ESTAO FORA DA UI** e mais coisas que não me lembro agora haha Estou compartilhando porque pode ser útil para outras pessoas da área, e também porque acho justo reconhecer que essa iniciativa só existiu porque o trabalho original me motivou a tentar fazer algo também Repositório: [Hidden Content] Se alguém quiser testar, dar feedback ou sugerir melhorias, vai ser muito bem-vindo. E LEMBRANDDO CRÉDITOS TOTAIS AO HAMILTON DO CANAL HC CURSOS E TUTORIAIS1 ponto
-
WYD FULL PVP 7662 E ai pessoal, eu tava meio a toa aqui e lembrei dessa release/source e resolvi dar uma editadinha pra ficar full PVP. Ela ja estava bem editava com os NPCs com os itens e tudo mais, mas faltava uns outros itens. O Cliente usado é o WReborn Updates: Destravar cele 40 = 100% de sucesso Destravar cele 90 = 100% de sucesso Poeira de fada = 100% de sucesso Comandos: /armia = Teleporte pra cidade de Armia /erion = Teleporte pra cidade de Erion /azran = Teleporte pra cidade de Azran /gelo = Teleporte pra cidade do Gelo /kefra = Teleporte pra cidade de Kefra /red = Teleporte pro Rei Red (Vermelho) /blue = Teleporte pro Rei Blue (Azul) /arch = Teleporte pra destravar levels 355/370 do Arch /destravar40 = Destrava o level 40 do celestial /combate = Teleporte pra enfrentar Mobs poderosos Na area de combate coloquei o Kefra e outros mobs la editados pra testar a força do seu personagem criado (não está 100%, mas da pra brincar ) DOWNLOAD [Hidden Content] DBSrv.exe [Hidden Content] TMSrv.exe [Hidden Content] Wyd.exe [Hidden Content] Creditos: WRebron por conta do cliente, a source/release eu acho que tbm sao eles que editaram a parte principal. Quem souber que foi o primeiro dono dessa release/source é so falar que edito aqui. vlw!1 ponto
-
Demonstração 1. Abra o CS2 2. depois de aberto, execute o Loader da FRCHEATS e logue em sua conta do fórum 3. Selecione a area CHEAT CS2 4.com CS2 aberto Clique em Injetar e aguarde a mensagem "Injetado com Sucesso" Após isso basta entrar em uma partida e apertar INSERT Bom jogo :) DOWNLOAD SENDSPACE: [Hidden Content]1 ponto
-
1 ponto
-
1 ponto
-
void BASE_GetCurrentScore(STRUCT_MOB_GLOBAL* MOB, STRUCT_AFFECT* Affect, STRUCT_EXT1* Ext1, STRUCT_EXT2* Ext2, int OriginalFace, int TargetX, int TargetY, int* AnotherSkill, int soultype, int* BuffState) //Função Ok { MOB->Rsv = 0; int MOBMagic = 0; memcpy(&MOB->CurrentScore, &MOB->BaseScore, sizeof STRUCT_SCORE); int tDamage = MOB->CurrentScore.Damage; int tMaxHp = MOB->CurrentScore.MaxHp; if (BASE_IsTranscended(OriginalFace) == 1) { //(0: Não iniciou a quest - 1: usou o cristal Elime - 2: usou o cristal Silphed - 3: usou o cristal Thelion - 4: usou o cristal Noas) for (int i = 0; i < 4; i++) { if (!BASE_TestByteBit(Ext2->Quest[1], i)) continue; int BonusMP = ResultQuest355[i][0]; int BonusAC = ResultQuest355[i][1]; int BonusHP = ResultQuest355[i][2]; MOB->CurrentScore.MaxMp += BonusMP; MOB->CurrentScore.Ac += BonusAC; tMaxHp += BonusHP; } } int acAdd = BASE_GetMobAbilityGlobal(MOB, EF_AC) + BASE_GetMobAbilityGlobal(MOB, EF_ACADD); tDamage += BASE_GetMobAbilityGlobal(MOB, EF_DAMAGE); tMaxHp += BASE_GetMobAbilityGlobal(MOB, EF_HP); MOB->CurrentScore.Ac += acAdd; MOB->CurrentScore.MaxMp += BASE_GetMobAbilityGlobal(MOB, EF_MP); MOB->CurrentScore.Str += BASE_GetMobAbilityGlobal(MOB, EF_STR); MOB->CurrentScore.Int += BASE_GetMobAbilityGlobal(MOB, EF_INT); MOB->CurrentScore.Dex += BASE_GetMobAbilityGlobal(MOB, EF_DEX); MOB->CurrentScore.Con += BASE_GetMobAbilityGlobal(MOB, EF_CON); int special0 = MOB->CurrentScore.Special[0] + BASE_GetMobAbilityGlobal(MOB, EF_SPECIAL1); if (special0 > MAX_SPECIAL_G) special0 = MAX_SPECIAL_G; int special1 = MOB->CurrentScore.Special[1] + BASE_GetMobAbilityGlobal(MOB, EF_SPECIAL2) + BASE_GetMobAbilityGlobal(MOB, EF_SPECIALALL); if (special1 > MAX_SPECIAL_G) special1 = MAX_SPECIAL_G; int special2 = MOB->CurrentScore.Special[2] + BASE_GetMobAbilityGlobal(MOB, EF_SPECIAL3) + BASE_GetMobAbilityGlobal(MOB, EF_SPECIALALL); if (special2 > MAX_SPECIAL_G) special2 = MAX_SPECIAL_G; int special3 = MOB->CurrentScore.Special[3] + BASE_GetMobAbilityGlobal(MOB, EF_SPECIAL4) + BASE_GetMobAbilityGlobal(MOB, EF_SPECIALALL); if (special3 > MAX_SPECIAL_G) special3 = MAX_SPECIAL_G; MOB->CurrentScore.Special[0] = special0; MOB->CurrentScore.Special[1] = special1; MOB->CurrentScore.Special[2] = special2; MOB->CurrentScore.Special[3] = special3; MOB->SaveMana = BASE_GetMobAbilityGlobal(MOB, EF_SAVEMANA); MOBMagic = BASE_GetMobAbilityGlobal(MOB, EF_MAGIC) + BASE_GetMobAbilityGlobal(MOB, EF_MAGICADD); int movSpeed = MOB->CurrentScore.AttackRun & 0xF; movSpeed += BASE_GetMobAbilityGlobal(MOB, EF_RUNSPEED); int attSpeed = BASE_GetMobAbilityGlobal(MOB, EF_ATTSPEED); int regenHP = BASE_GetMobAbilityGlobal(MOB, EF_REGENHP); int regenMP = BASE_GetMobAbilityGlobal(MOB, EF_REGENMP); int faceindex = MOB->Equip[FACE].sIndex; if (faceindex <= 0 || (faceindex >= 22 && faceindex <= 25) || faceindex == 32) //Transformações do BM faceindex = OriginalFace; int face = faceindex / 10; if (face < 4) { MOB->Equip[FACE].stEffect[0].cEffect = EF_SANC; MOB->Equip[FACE].stEffect[0].cValue = 0; if (MOB->Clan == 7 || MOB->Clan == 8 || MOB->Clan == 9) MOB->Clan = 0; int mountId = MOB->Equip[MOUNT].sIndex; int isNipple = FALSE; if ((TargetX / 128) >= 27 && (TargetX / 128) <= 30 && (TargetY / 128) >= 21 && (TargetY / 128) <= 24) //X 3456 - 3840 Y 2688 - 3072 isNipple = TRUE; if (isNipple) movSpeed -= 2; if (MOB->Equip[MOUNT].stEffect[0].sValue > 0) //Mount Hp { int nCategory = (mountId >= 1 && mountId < MAX_ITEMLIST) ? g_pItemList[mountId].nCategory : 0; if (nCategory == 22 || nCategory == 23) { int nSubCategory = g_pItemList[mountId].nSubCategory; if (nSubCategory >= 0 && nSubCategory < MOUNT_BONUS_ENTRIES) movSpeed = g_pMountBonusTable[nSubCategory].nMountSpeed; } } if (movSpeed < 0) movSpeed = 0; if (movSpeed > 6) movSpeed = 6; } if (BASE_IsTranscended(OriginalFace) == 1 && (MOB->LearnedSkill[0] & LEARN_30) != 0) //verifica se o personagem é Celestial+ checando a face e se tem soul { if (MOB->Class == 0) { tDamage += MOB->CurrentScore.Damage + 880; tMaxHp += 1600; MOB->CurrentScore.Ac += 950; MOB->CurrentScore.MaxMp += 300; } else if (MOB->Class == 1) { tDamage += 800; tMaxHp += 800; MOB->CurrentScore.Ac += 950; MOB->CurrentScore.MaxMp += 1700; } else if (MOB->Class == 2) { tDamage += 880; tMaxHp += 800; MOB->CurrentScore.Ac += 950; MOB->CurrentScore.MaxMp += 1300; } else if (MOB->Class == 3) { tDamage += 800; tMaxHp += 800; MOB->CurrentScore.Ac += 950; MOB->CurrentScore.MaxMp += 700; } } int capeId = MOB->Equip[CAPE].sIndex; //ebp-11c if (MOB->Clan != 4 && (capeId == 543 || capeId == 545 || capeId == 1766 || capeId == 1767 || capeId == 1768 || capeId == 3191 || capeId == 3194 || capeId == 3197 || capeId == 6447)) { MOB->Clan = 7; } if (MOB->Clan != 4 && (capeId == 544 || capeId == 546 || capeId == 1769 || capeId == 1770 || capeId == 1771 || capeId == 3192 || capeId == 3195 || capeId == 3198 || capeId == 6448)) { MOB->Clan = 8; } if (MOB->Clan != 4 && capeId == 1720) { MOB->Clan = 9; } if (MOB->Clan != 4 && (capeId == 734 || capeId == 736)) { MOB->Clan = 7; } if (MOB->Clan != 4 && (capeId == 735 || capeId == 737)) { MOB->Clan = 8; } if (MOB->Class == 3 && (MOB->LearnedSkill[0] & LEARN_02) != 0) //Agressividade { int weaponId = MOB->Equip[WEAPON].sIndex; if (weaponId > 0 && weaponId < MAX_ITEMLIST) { int itemUnique = g_pItemList[weaponId].nUnique; if (itemUnique == 42 || itemUnique == 43) //Arcos ou Garras { tDamage = tDamage * (special1 / 20 + 100) / 100; } } } int hpAdd = BASE_GetMobAbilityGlobal(MOB, EF_HPADD) + 100; tMaxHp = (tMaxHp * hpAdd) / 100; int mpAdd = BASE_GetMobAbilityGlobal(MOB, EF_MPADD) + 100; MOB->CurrentScore.MaxMp = (MOB->CurrentScore.MaxMp * mpAdd) / 100; for (int i = HELMET; i <= SHIELD; i++) { int equipId = MOB->Equip[i].sIndex; if (equipId <= 0 || equipId >= MAX_ITEMLIST) continue; int itemSanc = BASE_GetItemSanc(&MOB->Equip[i]); if (itemSanc < 9) continue; int itemPos = g_pItemList[equipId].nPos; if (itemPos == ARMOR_POS) MOB->CurrentScore.Ac += 25; else if (itemPos == PANTS_POS) MOB->CurrentScore.Ac += 25; else if (itemPos == GLOVES_POS) MOB->Rsv |= 64; else if (itemPos == SHIELD_POS) MOB->CurrentScore.Ac += 25; else if (itemPos == WEAPON_POS || itemPos == WEAPON2HAND_POS) { int itemUnique = g_pItemList[equipId].nUnique; if (itemUnique == 47) MOBMagic += 16; else if (itemUnique == 44) MOBMagic += 16; else tDamage += 40; } } int AttackSpeedBonus = 0; int RunSpeedBonus = 0; int DAMAGEMULTI = 100; int HPMULTI = 100; int MPMULTI = 100; int StatePlusHp = FALSE; int tMaxHPb = 0; *BuffState = 0; int Resist[4]{}; Resist[0] = MOB->Resist[0]; Resist[1] = MOB->Resist[1]; Resist[2] = MOB->Resist[2]; Resist[3] = MOB->Resist[3]; for (int i = 0; i < MAX_AFFECT; i++) { if (!Affect) continue; int Type = Affect[i].Type; if (!Type) continue; int Value = Affect[i].Value; int Level = Affect[i].Level; if (Type == 1) //Ice: Holy_Touch, Freeze_Spiral, Ice_Spear, Rock_Of_Blizzard, Thunder_Lising, Ice_Armor, Ambush { int scaledLevel = 4 * Level; if (scaledLevel >= 255) movSpeed -= 3; else movSpeed -= 1; if (Value == 1) *BuffState |= FROZEN; else if ((Value == 3 || Value == 50) && movSpeed > 1) movSpeed = 1; if (scaledLevel < 10) scaledLevel = 10; if (scaledLevel > 999) scaledLevel = 999; MOB->MultiHitThreshold = MOB->MultiHitThreshold * (1000 - scaledLevel) / 1000; } else if (Type == 2) //Velocity: Haste (Aceleração) { movSpeed += Value; *BuffState |= VELOCITY; } else if (Type == 3) //Pursuit: Double_Swing (Golpe Duplo), Resi_Decrease { int scaledLevel = 4 * Level; int decResist = Value; if (MOB->Equip[FACE].sIndex < 50) { if ((MOB->LearnedSkill[0] & LEARN_23) != 0) decResist = Value - 40; else decResist = Value - 30; } if (scaledLevel > 255) { int pct = scaledLevel / 50; if (pct > 99) pct = 99; Resist[0] = Resist[0] * (100 - pct) / 100; Resist[1] = Resist[1] * (100 - pct) / 100; Resist[2] = Resist[2] * (100 - pct) / 100; Resist[3] = Resist[3] * (100 - pct) / 100; } Resist[0] -= decResist; Resist[1] -= decResist; Resist[2] -= decResist; Resist[3] -= decResist; } else if (Type == 4) //Poções { if (Value == 0) { DAMAGEMULTI += 3; tDamage += 20; MOBMagic += 10; } else if (Value == 1) { DAMAGEMULTI += 5; tDamage += 40; MOBMagic += 12; } else if (Value == 2) { DAMAGEMULTI += 6; tDamage += 60; MOBMagic += 16; } else if (Value == 3) { DAMAGEMULTI += 15; tDamage += 80; MOBMagic += 20; } } else if (Type == 5) //Luster_Furnish, Incapacitate { *BuffState |= FROZEN; } else if (Type == 6) //Divine_Protection (Proteção Divina), Absolute_Protection { *BuffState |= INVULNERABLE; } else if (Type == 7) //Freeze_Blade (Lâmina Congelante) { int scaledLevel = 4 * Level; int decAttSpeed = (scaledLevel / 10) + 10; attSpeed -= decAttSpeed; if (MOB->Equip[FACE].sIndex > 50) { int calcInt = MOB->CurrentScore.Int; calcInt -= (decAttSpeed + 10); MOB->CurrentScore.Int = calcInt; } } else if (Type == 8) //PvP Jewels { if ((Value & 2) != 0) //Joia da Resistencia { int incResist = 25; Resist[0] += incResist; Resist[1] += incResist; Resist[2] += incResist; Resist[3] += incResist; } if ((Value & 16) != 0) //Joia da Proteção (+HP +Def) { tMaxHp = (tMaxHp + (MOB->CurrentScore.Level / 2)) + ((MOB->CurrentScore.Ac * 20) / 100); } if ((Value & 32) != 0) //Joia do Poder (+Ataque +HP) { DAMAGEMULTI += 5; MOBMagic += 4; tMaxHp = (107 * tMaxHp) / 100; } if ((Value & 128) != 0) //Joia Magia (MP -> HP) { StatePlusHp = TRUE; } } else if (Type == 9) //Magic_Weapon (Arma Mágica) { int scaledLevel = 4 * Level; int incAttack = (scaledLevel / 3) + 15; DAMAGEMULTI += 5; if (MOB->Class == 1) { if ((MOB->LearnedSkill[0] & LEARN_20) != 0) //Arma Magica { DAMAGEMULTI += 15; incAttack *= 5; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) //8 Skill Magia Especial DAMAGEMULTI += 7; } // LearnedSkill[1] & 0x400 (nLEARN_10) — Special_Master (11th FM Especial): +5% buff dano if ((MOB->LearnedSkill[1] & nLEARN_10) != 0) { incAttack += incAttack / 20; DAMAGEMULTI += DAMAGEMULTI / 20; } } tDamage += incAttack; } else if (Type == 10) //Waste (Enfraquecimento) { int scaledLevel = 4 * Level; if (scaledLevel >= 255) { int pct = scaledLevel / 60; if (pct > 99) pct = 99; tDamage = tDamage * (100 - pct) / 100; } tDamage -= Value + scaledLevel / 5; } else if (Type == 11) //Magic_Shield (Escudo Mágico) { if (Value == 1) MOB->CurrentScore.Ac *= 2; else { int scaledLevel = 4 * Level; int incDef = Value + scaledLevel / 3; // FM class — percentage multiplier (100% base, 102% com LEARN_23, +5% com Special_Master 11th) if (MOB->Class == 1) { int acPct = 100; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) acPct = 102; if ((MOB->LearnedSkill[1] & nLEARN_10) != 0) acPct += 5; MOB->CurrentScore.Ac = acPct * MOB->CurrentScore.Ac / 100; } MOB->CurrentScore.Ac += incDef; } } else if (Type == 12) // { float incDef = (100 - Value) / 100.0; MOB->CurrentScore.Ac *= incDef; } else if (Type == 13) //Assault (Investida) { int calcBonus = MOB->CurrentScore.Special[2] / 10 + Value; DAMAGEMULTI += calcBonus; if ((MOB->LearnedSkill[0] & LEARN_15) != 0) //8 Skill Trans DAMAGEMULTI += 5; // LearnedSkill[1] bit 7 (nLEARN_07) — WindStorm (12th TK Trans): elimina HP penalty, +DMG if ((MOB->LearnedSkill[1] & nLEARN_07) == 0) HPMULTI -= 10; else DAMAGEMULTI += 2; } else if (Type == 14) //Growth (Crescimento/Samaritano) { int useLvl = MOB->CurrentScore.Level; if (BASE_IsTranscended(OriginalFace) == 1 && (MOB->LearnedSkill[0] & LEARN_30) != 0) useLvl += 400; int calcCon = Value + 6 * MOB->CurrentScore.Special[1] + 4 * useLvl / 3 + MOB->CurrentScore.Con; int Increase = 0; int incSpecial = 0; if ((MOB->LearnedSkill[0] & LEARN_07) != 0) //8 Skill Confianca { Increase = 400; incSpecial = 6 * MOB->CurrentScore.Special[1]; } MOB->CurrentScore.Dex += Increase; MOB->CurrentScore.Int += Increase; MOB->CurrentScore.Str += Increase; MOB->CurrentScore.Con = Increase + incSpecial + calcCon; } else if (Type == 15) //Skill_Amplify (Amplificação/Athena) { int scaledLevel = 4 * Level; int incSpecial = (scaledLevel / 10) + Value; if (MOB->Class == 1 && (MOB->LearnedSkill[0] & LEARN_23) != 0) incSpecial = 120 * incSpecial / 100; MOB->CurrentScore.Special[0] += incSpecial; MOB->CurrentScore.Special[1] += incSpecial; MOB->CurrentScore.Special[2] += incSpecial; MOB->CurrentScore.Special[3] += incSpecial; // Special_Master (11th FM Especial): +10% bonus a cada special if (MOB->Class == 1 && (MOB->LearnedSkill[1] & nLEARN_10) != 0) { MOB->CurrentScore.Special[0] = 110 * MOB->CurrentScore.Special[0] / 100; MOB->CurrentScore.Special[1] = 110 * MOB->CurrentScore.Special[1] / 100; MOB->CurrentScore.Special[2] = 110 * MOB->CurrentScore.Special[2] / 100; MOB->CurrentScore.Special[3] = 110 * MOB->CurrentScore.Special[3] / 100; } if (MOB->CurrentScore.Special[0] > MAX_SPECIAL_G) MOB->CurrentScore.Special[0] = MAX_SPECIAL_G; if (MOB->CurrentScore.Special[1] > MAX_SPECIAL_G) MOB->CurrentScore.Special[1] = MAX_SPECIAL_G; if (MOB->CurrentScore.Special[2] > MAX_SPECIAL_G) MOB->CurrentScore.Special[2] = MAX_SPECIAL_G; if (MOB->CurrentScore.Special[3] > MAX_SPECIAL_G) MOB->CurrentScore.Special[3] = MAX_SPECIAL_G; } else if (Type == 16) //Transform: Werewolf, Werebear, Astaroth, Titan, Evilator { int transfId = Value - 1; if (transfId > EDEN || MOB->Class != 2) continue; if (transfId == EDEN) MOB->Equip[FACE].sIndex = 32; else MOB->Equip[FACE].sIndex = transfId + 22; int faceId = MOB->Equip[FACE].sIndex; int damAdd = 0; int hpAdd = 0; int acAdd = 0; int attSpeedAdd = 0; int resistAdd = 0; if (faceId == 25) //Titan { resistAdd = pTransBonus[transfId].MinResist; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) acAdd = 10; } else if (faceId == 32) //Eden { attSpeedAdd = 10; resistAdd = pTransBonus[transfId].MinResist; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) { damAdd = 5; acAdd = 2; } } else if ((MOB->LearnedSkill[0] & LEARN_21) != 0) //Metamorfose Superior { resistAdd = pTransBonus[transfId].MinResist; if (faceId == 22) //Lobisomem { MOB->Critical = pTransBonus[transfId].MinCritical + ((MOB->CurrentScore.Special[3] / 50) * pTransBonus[transfId].MaxCritical); damAdd = 10; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) { damAdd = 15; acAdd = 2; } } else if (faceId == 23) //Homem Urso { hpAdd = 20; attSpeedAdd = 20; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) { damAdd = 5; acAdd = 2; } } else if (faceId == 24) //Astaroth { attSpeedAdd = 20; damAdd = 10; if ((MOB->LearnedSkill[0] & LEARN_23) != 0) { damAdd = 15; acAdd = 2; } } } int sancFace = 0; if (BASE_IsTranscended(OriginalFace) == 1 && (MOB->LearnedSkill[0] & LEARN_30) != 0) sancFace = 9; else { sancFace = ((MOB->CurrentScore.Special[3] + 2 * MOB->CurrentScore.Level) / 3 - pTransBonus[transfId].Sanc) / 12; if (sancFace < 0) sancFace = 0; if (sancFace > 9) sancFace = 9; } MOB->Equip[FACE].stEffect[0].cEffect = EF_SANC; MOB->Equip[FACE].stEffect[0].cValue = sancFace; int sp3 = MOB->CurrentScore.Special[3]; //Calculo do Dano DAMAGEMULTI = (DAMAGEMULTI + damAdd + pTransBonus[transfId].MinAttack + (sp3 * (pTransBonus[transfId].MaxAttack - pTransBonus[transfId].MinAttack) / 200)) - 100; //Calculo da Defesa int calcAc = MOB->CurrentScore.Ac * (acAdd + pTransBonus[transfId].MinDefense + sp3 * (pTransBonus[transfId].MaxDefense - pTransBonus[transfId].MinDefense) / 200) / 100; if (faceId == 22) calcAc += 5; MOB->CurrentScore.Ac = calcAc; //Calculo do Hp tMaxHp = tMaxHp * (hpAdd + pTransBonus[transfId].MinHp + sp3 * (pTransBonus[transfId].MaxHp - pTransBonus[transfId].MinHp) / 200) / 100; //Calculo das Resistencias Resist[0] += resistAdd; Resist[1] += resistAdd; Resist[2] += resistAdd; Resist[3] += resistAdd; //Calculo SpeedAttack AttackSpeedBonus = pTransBonus[transfId].SpeedAttack + attSpeedAdd; //Velocidade de Movimento RunSpeedBonus = pTransBonus[transfId].SpeedMove; } else if (Type == 18) //Mana_Control (Controle de Mana) { *BuffState |= MANACONTROL; } else if (Type == 19) //Immunity (Imunidade) { *BuffState |= CANCEL; } else if (Type == 21) //Transfer_Armor_Class (Meditação) { int sp1 = MOB->CurrentScore.Special[1]; MOB->CurrentScore.Ac += -10 - sp1 / 3; int incDmg = sp1 / 10 + Value; if ((MOB->LearnedSkill[0] & LEARN_07) != 0) incDmg += 5; DAMAGEMULTI += incDmg; } else if (Type == 24) //Rescue (Possuído/Berserker) { MOB->CurrentScore.Ac += 5 * MOB->CurrentScore.Special[2]; if (BASE_GetItemAbility(&MOB->Equip[SHIELD], EF_POS) == SHIELD_POS) { MOB->BerserkerResist += 10; Resist[0] += 20; Resist[1] += 20; Resist[2] += 20; Resist[3] += 20; } if ((MOB->LearnedSkill[0] & LEARN_15) != 0) MOB->BerserkerResist += 20; } else if (Type == 25) //Elemental_Protector (Proteção Elemental) { int sp2 = MOB->CurrentScore.Special[2]; int incResist = (sp2 / 4 + Value); if (sp2 >= 255) { int pctBoost = (sp2 - 255) / 15; if (pctBoost > 0) { Resist[0] = (pctBoost + 100) * Resist[0] / 100; Resist[1] = (pctBoost + 100) * Resist[1] / 100; Resist[3] = (pctBoost + 100) * Resist[3] / 100; } } Resist[0] += incResist / 10; Resist[1] += incResist / 10; Resist[3] += incResist / 10; } else if (Type == 26) //Dodge (Evasão Aprimorada) { *BuffState |= EVASION; } else if (Type == 27) //Enchant_Frost (Encantar Gelo) { *BuffState |= FREEZE; } else if (Type == 28) //Hide_In_Shadow (Invisibilidade) { *BuffState |= INVISIBLE; } else if (Type == 29) //Soul_Of_Limits (Limite da Alma) / Weapon_Mastery { // HT bonus +20% se Class==3 e LearnedSkill[1] bit 7 (nLEARN_07) int htBonus = 0; if (MOB->Class == 3 && (MOB->LearnedSkill[1] & nLEARN_07) != 0) htBonus = 20; int _nIncreese = 1; if (BASE_IsTranscended(OriginalFace) == 1) _nIncreese = 2; if ((MOB->LearnedSkill[0] & LEARN_30) != 0) { if (soultype < 1 || soultype > 10) soultype = 1; switch (soultype) { case 1: { MOB->CurrentScore.Str += MOB->CurrentScore.Str * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Con += MOB->CurrentScore.Con * (htBonus + 30 * _nIncreese) / 100; } break; case 2: { MOB->CurrentScore.Int += MOB->CurrentScore.Int * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Con += MOB->CurrentScore.Con * (htBonus + 30 * _nIncreese) / 100; } break; case 3: { MOB->CurrentScore.Dex += MOB->CurrentScore.Dex * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Con += MOB->CurrentScore.Con * (htBonus + 30 * _nIncreese) / 100; } break; case 4: { MOB->CurrentScore.Str += MOB->CurrentScore.Str * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Dex += MOB->CurrentScore.Dex * (htBonus + 30 * _nIncreese) / 100; } break; case 5: { MOB->CurrentScore.Int += MOB->CurrentScore.Int * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Dex += MOB->CurrentScore.Dex * (htBonus + 30 * _nIncreese) / 100; } break; case 6: { MOB->CurrentScore.Con += MOB->CurrentScore.Con * (htBonus + 40 * _nIncreese) / 100; MOB->CurrentScore.Dex += MOB->CurrentScore.Dex * (htBonus + 30 * _nIncreese) / 100; } break; case 7: { MOB->CurrentScore.Str += MOB->CurrentScore.Str * (htBonus + 60 * _nIncreese) / 100; } break; case 8: { MOB->CurrentScore.Int += MOB->CurrentScore.Int * (htBonus + 60 * _nIncreese) / 100; } break; case 9: { MOB->CurrentScore.Con += MOB->CurrentScore.Con * (htBonus + 60 * _nIncreese) / 100; } break; case 10: { MOB->CurrentScore.Dex += MOB->CurrentScore.Dex * (htBonus + 60 * _nIncreese) / 100; } break; } } else if (_nIncreese == 1) { MOB->CurrentScore.Str = 2000; MOB->CurrentScore.Int = 2000; tMaxHPb = 10000; } if (MOB->CurrentScore.Str >= MAX_STATSPOINT) MOB->CurrentScore.Str = MAX_STATSPOINT; if (MOB->CurrentScore.Int >= MAX_STATSPOINT) MOB->CurrentScore.Int = MAX_STATSPOINT; if (MOB->CurrentScore.Con >= MAX_STATSPOINT) MOB->CurrentScore.Con = MAX_STATSPOINT; if (MOB->CurrentScore.Dex >= MAX_STATSPOINT) MOB->CurrentScore.Dex = MAX_STATSPOINT; } else if (Type == 31) //Coin_Armor (Escudo Dourado) { int scaledLevel = 4 * Level; int incDef = (scaledLevel / 10) + Value; if ((MOB->LearnedSkill[0] & LEARN_15) != 0) incDef += 100; // Plunder (11th HT Troca): +10% AC no Escudo Dourado if ((MOB->LearnedSkill[1] & nLEARN_06) != 0) incDef += 10 * MOB->CurrentScore.Ac / 100; MOB->CurrentScore.Ac += incDef; } else if (Type == 33) //Scroll Transform (pergaminho) { int setFace = 0; if (Value == 0) setFace = 202; //Gremlin if (Value == 1) setFace = 209; //Arqueiro Orc if (Value == 2) setFace = 212; //Troll Machado if (Value == 3) setFace = 230; //Carbunkle if (Value == 4) setFace = 229; //Chefe Zumbi if (Value == 5) setFace = 216; //Javali Selvagem if (Value == 6) setFace = 226; //Lobo if (Value == 7) setFace = 298; //Golem Chefe MOB->Equip[FACE].sIndex = setFace; } else if (Type == 34) //Divine Potion { DAMAGEMULTI += 20; tDamage += 160; MOBMagic += 40; HPMULTI += 30; MPMULTI += 30; } else if (Type == 35) //Vigor Potion (sem skill — poção) { if (Affect[i].Time >= 1000000) { HPMULTI += 30; MPMULTI += 30; } else { HPMULTI += 10; MPMULTI += 10; } } else if (Type == 36) //Critical_Armor / Venom (Veneno) { *BuffState |= POISON; } else if (Type == 37) //Another_Soul (Ligação Espectral) { *AnotherSkill = 3 * (MOB->CurrentScore.Special[2] / 10 + 8); } else if (Type == 38) //Spirit_Change (Troca de Espírito) / Improved_Range { int useLvl = MOB->CurrentScore.Level; if (BASE_IsTranscended(OriginalFace) == 1) { if ((MOB->LearnedSkill[0] & LEARN_30) != 0) useLvl += 400; int mana = MOB->CurrentScore.MaxMp / 4; tMaxHp += mana + (MOB->CurrentScore.Special[2] / 2) + 2 * useLvl + 750; MOB->CurrentScore.MaxMp -= mana; } else { int mana = MOB->CurrentScore.MaxMp / 4 + (MOB->CurrentScore.Special[2] + useLvl) / 4; tMaxHp += mana + 750; MOB->CurrentScore.MaxMp -= mana; } } else if (Type == 41) //Flash / Clod_Attack { *BuffState |= FLASH; } else if (Type == 42) //Mystery_Magic (Magia Misteriosa) { MOBMagic += 20; } else if (Type == 45) //Ice_Binding (Aprisionamento de Gelo) { *BuffState |= 0x2000; } else if (Type == 48) //Last_Resistance (Última Resistência) { HPMULTI += Value; MOB->CurrentScore.Ac += Value * MOB->CurrentScore.Ac / 100; } else if (Type == 51) //HP buff (sem skill) { if (Value) tMaxHp += 5 * tMaxHp / 100; } else if (Type == 53) //TowerWarBuff (buff de Guerra de Torre / Siege) { if (Level >= 0 && Level < TOWERWAR_BUFF_ROWS) { const auto& row = g_pTowerWarBuff[Level]; for (int j = 0; j < TOWERWAR_BUFF_SLOTS; j++) { int bType = row.nType[j]; int bValue = row.nValue[j]; if (bType == 0 || bValue == 0) continue; switch (bType) { case 4: // HP flat bonus tMaxHp += bValue; break; case 26: // Attack Speed bonus attSpeed += bValue; break; case 54: // All Resistances bonus Resist[0] += bValue; Resist[1] += bValue; Resist[2] += bValue; Resist[3] += bValue; break; case 74: // All Specials bonus (cap MAX_SPECIAL_G) { int s0 = bValue + MOB->CurrentScore.Special[0]; int s1 = bValue + MOB->CurrentScore.Special[1]; int s2 = bValue + MOB->CurrentScore.Special[2]; int s3 = bValue + MOB->CurrentScore.Special[3]; if (s0 > MAX_SPECIAL_G) s0 = MAX_SPECIAL_G; if (s1 > MAX_SPECIAL_G) s1 = MAX_SPECIAL_G; if (s2 > MAX_SPECIAL_G) s2 = MAX_SPECIAL_G; if (s3 > MAX_SPECIAL_G) s3 = MAX_SPECIAL_G; MOB->CurrentScore.Special[0] = s0; MOB->CurrentScore.Special[1] = s1; MOB->CurrentScore.Special[2] = s2; MOB->CurrentScore.Special[3] = s3; } break; } } } } } if (face < 4) { tDamage += (MOB->CurrentScore.Str >> 1) + (MOB->CurrentScore.Dex / 12) + MOB->CurrentScore.Special[0]; if (faceindex % 10 <= 5) tDamage += MOB->CurrentScore.Level; else tDamage += (MOB->CurrentScore.Level * 2); } for (int i = 0; i <= 3; i++) { if (Resist[i] < 0) Resist[i] = 0; if (Resist[i] > MAX_RESIST_G) Resist[i] = MAX_RESIST_G; MOB->Resist[i] = (int16_t)Resist[i]; } if (DAMAGEMULTI != 100) tDamage = (tDamage * DAMAGEMULTI) / 100; if (HPMULTI != 100) { int PlusMaxHp = (tMaxHp * HPMULTI) / 100; if (PlusMaxHp > MAX_MAXHP_G) PlusMaxHp = MAX_MAXHP_G; tMaxHp = PlusMaxHp; } if (MPMULTI != 100) { int PlusMaxMp = (MOB->CurrentScore.MaxMp * MPMULTI) / 100; if (PlusMaxMp > MAX_MAXMP_G) PlusMaxMp = MAX_MAXMP_G; MOB->CurrentScore.MaxMp = PlusMaxMp; } if (StatePlusHp == TRUE) //Converte Metade do MP em HP { tMaxHp += MOB->CurrentScore.MaxMp / 2; MOB->CurrentScore.MaxMp /= 2; } if (regenHP < 0) regenHP = 0; if (regenHP > MAX_REGEN_G) regenHP = MAX_REGEN_G; MOB->RegenHP = (int16_t)regenHP; if (regenMP < 0) regenMP = 0; if (regenMP > MAX_REGEN_G) regenMP = MAX_REGEN_G; MOB->RegenMP = (int16_t)regenMP; movSpeed += RunSpeedBonus; if (movSpeed < 0) movSpeed = 0; if (movSpeed > MAX_MOVSPEED_G) movSpeed = MAX_MOVSPEED_G; int attFinal; if (face >= 4) { int mobAttSpeed = AttackSpeedBonus + MOB->CurrentScore.Dex / 5 + attSpeed; if (mobAttSpeed < 0) mobAttSpeed = 0; if (mobAttSpeed > MAX_MOB_ATTSPEED_G) mobAttSpeed = MAX_MOB_ATTSPEED_G; attFinal = (mobAttSpeed / 10) & 0xF; } else { attFinal = BASE_GetDiminishedAttackSpeed(MOB->CurrentScore.Dex) + attSpeed; } MOB->MultiHitThreshold = (int16_t)attFinal; MOB->CurrentScore.AttackRun = movSpeed + 16 * attFinal; int mobMerchant = MOB->Merchant; if (face >= 4) { if (MOB->Merchant >= 100 && MOB->Merchant < 200) mobMerchant = 8; } else { // Exp death penalty if (BASE_IsTranscended(OriginalFace) == 1 && (MOB->LearnedSkill[0] & LEARN_30) != 0) { long long curExp = g_pNextLevel_2[MOB->BaseScore.Level]; long long nextExp = g_pNextLevel_2[MOB->BaseScore.Level + 1]; int calcExp = (int)((nextExp - curExp) / 10); if (Ext1->Data[0] >= calcExp) MOB->CurrentScore.Ac /= 2; } else { long long curExp = g_pNextLevel[MOB->BaseScore.Level]; long long nextExp = g_pNextLevel[MOB->BaseScore.Level + 1]; int calcExp = (int)((nextExp - curExp) / 10); if (Ext1->Data[0] >= ((calcExp * 4) / 5)) MOB->CurrentScore.Ac /= 2; } } MOB->CurrentScore.Reserved = ((MOB->CurrentScore.Reserved & 240) | mobMerchant); MOB->SkillMagic = (int16_t)(MOBMagic / 4); if (tDamage > MAX_DAMAGE_G) tDamage = MAX_DAMAGE_G; MOB->CurrentScore.Damage = tDamage; if (tMaxHp > MAX_MAXHP_G) tMaxHp = MAX_MAXHP_G; MOB->CurrentScore.MaxHp = tMaxHp; if (MOB->CurrentScore.Hp > MOB->CurrentScore.MaxHp) MOB->CurrentScore.Hp = MOB->CurrentScore.MaxHp; if (MOB->CurrentScore.Mp > MOB->CurrentScore.MaxMp) MOB->CurrentScore.Mp = MOB->CurrentScore.MaxMp; } STRUCT_MOB_GLOBAL tem 1368 bytes STRUCT_ITEM_GLOBAL tem 12 bytes A maioria dos cálculos e bônus das skills estão ai, devidamente atualizados com a versão atual do Global.1 ponto
-
LINK ATUALIZADO 02/04/2026: [Hidden Content] PATROCINADORA streamingsbarato.com Diversos Serviços streamings com 70% OFF1 ponto
-
Esta sendo feito para o cliente em DX11 porem pode ser implementado na TMProject original. Gif1 ponto
-
[Hidden Content] [Hidden Content]1 ponto
-
🏆 🌟 Seja um Herói no WYD Legends Of Midgard! 🌟 Reviva a nostalgia do WYD com Legends of Midgard! Um MMORPG renovado, com mecânicas avançadas, farm estratégico e PvP épico. Junte-se à batalha e escreva a sua lenda. Midgard precisa de você! No Legends Of Midgard, você pode vender seus itens e 𝗿𝗲𝗰𝗲𝗯𝗲𝗿 𝗽𝗮𝗴𝗮𝗺𝗲𝗻𝘁𝗼𝘀 𝘃𝗶𝗮 𝗣𝗜𝗫! 𝗖𝗼𝗺𝗼 𝗙𝘂𝗻𝗰𝗶𝗼𝗻𝗮: -Anuncie seus itens no NPC "Market" utilizando Rubis. -Compradores adquirem os itens com Rubis e você recebe o pagamento. -Retire seus ganhos via PIX com facilidade e segurança. Transforme suas conquistas no jogo em dinheiro real! Jogue Legends Of Midgard, 𝗼 𝗺𝗲𝗹𝗵𝗼𝗿 𝘀𝗲𝗿𝘃𝗶𝗱𝗼𝗿 𝗱𝗮 𝗮𝘁𝘂𝗮𝗹𝗶𝗱𝗮𝗱𝗲, e faça dinheiro com seus itens valiosos. 𝗖𝗼𝗺𝗲𝗰𝗲 𝗔𝗴𝗼𝗿𝗮 𝗠𝗲𝘀𝗺𝗼! 𝗦𝗶𝘁𝗲 𝗢𝗳𝗶𝗰𝗶𝗮𝗹 𝗜𝗻𝘀𝘁𝗮𝗴𝗿𝗮𝗺 𝗗𝗶𝘀𝗰𝗼𝗿𝗱 𝗚𝗿𝘂𝗽𝗼 𝗪𝗵𝗮𝘁𝘀𝗔𝗽𝗽 Mais informações basta logar no Site >Market>Como funciona?1 ponto
-
🎮 WYD ELDORIA — EXPERIÊNCIA ÚNICA E RECOMPENSADORA! 🎮 🌟 Versão do Servidor: 7.99 🌟 ✨ Detalhes do Servidor: Drop: Medio/Clássico ⚡ Up: Medio/Medio 🚀 Composição: 40% ⚔️ 🔥 Evoluções liberadas no servidor 🔥 👤 Mortal — até level 400 🛡 Arch — até level 400 ✨ Celestial / Sub-Celestial — até level 200 💡 Sistemas Exclusivos 💡 🗃️ Droplist com filtro de drop 🗃️ Sistema Lan Mortal 351+ 🗃️ Sistema Lan Arch 300+ 🗃️ Sistema de Fragmentos das Almas 🗃️ Sistema GOLD do servidor LAN/GELO/SUBMUNDO 🗃️ Sistema Vale apenas ARCH/CELE (desativado inicio) 🔍 Limite de conta (3) ⚔️ Arena Real 🌍 Sistema Guerra entre Reinos 🔍 Player Info 🏆 Ranking Atualizado / PVP / LEVEL 🌊 Pergaminho Água com Macro ⚖️ Sistema de Balanceamento: PVP e PVE 🔒 Sistema Vip / Painel Vip 🎒 Sistema de Boss Com drop de DONATE / Painel Boss 🗄️ RMT Mercado Global 🖥️ Resoluções Widescreen sem distorções 🛒 Loja Fantasma: Progrida livremente enquanto ganha recompensas em moedas! 📦 Loja de Donate: Abra em qualquer lugar! 🔧 Novidades de Npcs Composição e Recursos: ⚙️ Recicladores 💎 Novos slots para colar e cinto 🌍 Sistema Exclusivo TOP KILL semanal arena ⚙️ Outras Novidades 🔗 Horarios do Servidor 🔗 GUERRA DE CIDADES: Horario: 20:00 (Domingo) GUERRA DE NOATUN: Horario: 21:00 (Domingo) GUERRA DE TORRES: Horario: 22:00 (Segunda a Sexta) KEFRA: Horario: 10:00 (Segunda) GUERRA ENTRE REINOS (RVR): Horario: 20:00 (Segunda a Sexta) 🔥 POR QUE ESCOLHER O WYD ELDORIA? 🔥 ✅ Atendimento via Discord, Whatsapp ✅ Equipe de GM’s e MOD’s 24H ✅ Time dedicado, sempre ouvindo os players! 💬 QUER FICAR POR DENTRO DAS NOVIDADES? Fique ligado, em breve revelaremos nossos parceiros e divulgadores oficiais! 💪 🔗 LINKS ÚTEIS 🔗 🌐 Site:[Hidden Content] 🎙️ Discord:[Hidden Content] 📱 Grupo do WhatsApp:[Hidden Content] 🌟 Prepare-se para viver a melhor aventura MMORPG com o WYD ELDORIA! 🌟1 ponto
-
QUICK LIST Para procurar algo com mais facilidade dê um CTRL + F para buscar! Cliente Todos os Clientes do WYD disponiveis e patchs de atualizações Hook's Hook de resolução HD - Widscreen 7.56 Source & Release Versão 7.54 Versão 7.56 Versão 7.59 / 7.62 Codigos e Hook's Leitura da ItemList em Runtime Macro ItemList [HOOK] Retirar barra de HP de novas esferas [HOOK] Additemsanc 759 [HOOK] Widscreen 762 [HOOK] Mofificar atributos das montarias-759 [HOOK] Adicionar-novos-trajes-759 [HOOK] Trajes com brilho 759 [HOOK] createscene world mobtarget-759 [HOOK] Additemsanc-759 [HOOK] Trajes Completo 759 Exemplos de npcs de evento [HOOK] [FIX] crash no pacote-0xfdf 756 [HOOK] Side maps 7556 [HOOK] Resoluções FULL HD [HOOK] Adicionando local e o valor do cp 7556 [HOOK] Modo foto no wyd [HOOK] Native Func 756 atualizada para 754 cliente [PARTE 1] [HOOK] Native Func 756 atualizada para 754 cliente [PARTE 2] [HOOK] Keypress newbutton 754 [HOOK] Fixmobcount contador laranja 754 Tool's E-MAPS Editor Source Fieldscene editor Leitura da itemlistcsv runtime Macro itemlist by seitbnao [TOOL] Meshtexturelist meshs wyd.exe para novos trajes [7.59] Editor e conversor skilldata v761 [TOOL] Editor serverlist bin WYD Global W2 mixlist editor Launcher customizado e traduzido [SOURCE] Wyd launcher by seitbnao WebSite Artes e .PSD PSD imagem para divulgação PSD imagem para divulgação 2 PSD imagem para divulgação 3 PSD imagem para divulgação 4 PSD imagem para divulgação 5 PSD imagem para divulgação 6 Outros Pacote de Guildmark Trajes separados e organizados Links dos clientes e patchs de atualizações by Reechdan Novos psds para client 756 Icones itens wyd Pack de DLL para melhorar os graficos 756 Struct do config.bin do launcher [SOURCE] Premium neil wyd Re-Ups Caso algum link esteja offline, contate a moderação do Fórum! QuickList será atualizada a cada 15 dias por um Moderador da área caso tenha algum novo tópico relevante. Atenciosamente, Equipe Webcheats1 ponto
-
1 ponto
-
1 ponto
-
📖 Tutorial Completo – kwy Chess Bot no Navegador ⚠️ Aviso importante: Este projeto é apenas para estudo e demonstração técnica. O uso em partidas ranqueadas pode violar os Termos de Serviço de plataformas como Chess.com e Lichess. 🟢 Parte 1 – Para Jogadores (passo a passo simples) 🔹 O que o bot faz Mostra a melhor jogada no tabuleiro Pode jogar automaticamente por você Desenha uma seta indicando o movimento Ajusta a força do motor, velocidade, chance de erro proposital (blunder) Permite iniciar automaticamente novas partidas 🔹 Pré-requisitos Abra uma partida ativa no Chess.com Pode ser contra outra pessoa ou contra o bot de treino. O script só funciona quando o tabuleiro está carregado e pronto. Ter acesso ao console do navegador (funciona no Chrome, Edge, Firefox, Brave). 🔹 Instalação e uso Vá para Chess.com → Jogar e inicie uma partida real. Quando o tabuleiro estiver na tela, pressione: F12 (ou Ctrl + Shift + I) → abre as ferramentas de desenvolvedor Clique na aba Console [Hidden Content] Cole no console e pressione Enter. Se tudo der certo, vai aparecer no canto da tela uma janela chamada kwy Smart Assist. 🔹 Como usar na prática Enable Bot → ativa o bot Show Arrow → seta indicando a melhor jogada Auto Move → faz o bot jogar automaticamente Blunder Chance → insere erros aleatórios (para parecer humano) Time Control → ajusta o tempo da partida (1 min, 3 min, 5 min, etc.) Atalhos rápidos: Ctrl + B → mostra/esconde o menu do bot 💡 Dica: Se não aparecer nada, recarregue a partida e cole o código de novo. 🔹 Exemplo ⚙️ Parte 2 – Para Desenvolvedores (detalhes técnicos) 🔹 Estrutura do projeto O script é dividido em três camadas principais: UI (Interface do usuário) Criada dinamicamente em createUI() Usa elementos HTML/CSS inline para exibir os botões e sliders Toggle rápido com Ctrl + B Hook do Bot O código “escuta” os movimentos do jogador e do adversário Envia a posição atual do tabuleiro para o motor Stockfish (WebAssembly) Recebe o melhor movimento e decide o que mostrar/fazer Engine (Stockfish) Roda direto no navegador via WebAssembly Suporta profundidade variável (depth) Ajuste de nível (engine strength) para simular jogadores de diferentes ELOs 🔹 Configurações importantes Profundidade de busca (Max Depth) Controla o número de jogadas futuras analisadas. Exemplo: const DEFAULT_DEPTH = 18; // pode aumentar para 25 para mais precisão Nível de força (Engine Strength) Vai de 0 (muito fraco) até 20 (forte como GM). Blunders (erros simulados) A função adiciona jogadas ruins aleatórias para não parecer “perfeito demais”. 🔹 Customizações possíveis Alterar atalho do painel Exemplo, trocar Ctrl + B por Ctrl + M: if (event.ctrlKey && event.key === 'm') { toggleBotUI(); } Mudar o visual da UI Dentro de createUI(), pode editar os estilos inline (cores, tamanhos, posição). Integrar outro motor É possível substituir o Stockfish por Lc0 (Leela), desde que compilado em WASM. ✅ Resumo O bot só funciona quando você já está em uma partida aberta (contra humano ou bot). Para jogadores comuns → basta colar o código no console. Para devs → há várias formas de personalizar e expandir a ferramenta.1 ponto
-
Creditos do desenvolvimento e vídeo do nosso amigo Mizael [Hidden Content]1 ponto
-
Trago pra vocês um canal no telegram com atualizações diárias, tem muito material. Aproveitem. [Hidden Content]1 ponto
Esta tabela de classificação está definida para São Paulo/GMT-03:00
