当前位置: 首页 > news >正文

92.网络游戏逆向分析与漏洞攻防-游戏技能系统分析-利用哈希表实现快速读取文本内容

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了

内容参考于:易道云信息技术研究院

上一个内容:91.加载游戏语言文件到内存

码云版本号:aafa72010a0c9ffb42274c1c2ff3a61e627eb49f

代码下载地址,在 titan 目录下,文件名为:titan-利用哈希表实现快速读取文本内容.zip

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg

提取码:q9n5

--来自百度网盘超级会员V4的分享

HOOK引擎,文件名为:黑兔sdk升级版.zip

链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw

提取码:78h8

--来自百度网盘超级会员V4的分享

以 91.加载游戏语言文件到内存 它的代码为基础进行修改

现在已经把游戏里的语言文件写到了本次磁盘里,并且把这个文件加载到了我们程序的内存中

找有冲突的中文

下图红框里是 textDatas 变量的地址,也就是从磁盘文件中加载的语言包的地址

然后打开x96dbg,然后附加到游戏

鼠标单击下图红框位置,也就是x96dbg的内存窗口位置

然后ctrl+g,然后输入,textDatas 变量的地址

如下图,在7CCFF27C位置鼠标右击选择在内存窗口中转到知道DWORD

然后就来到了语言包的内存区域,现在还没有赋值所以全是0

然后回到游戏点击确定,如下图红框

点击完确定就会有值了

这个原因是,弹框的代码是在解析语言包之前

然后第一个不是-1,它就是存在哈希冲突

然后找它的链表,上图是链表第一个数据,通过下图得出的589A8740是链表的第二个数据,现在要找链表的最后一个数据,找最后一个数据的愿意是为了测试我们通过磁盘文件加载的语言包是否可以用,然后DAC*30,这个30是十六进制的,30的十进制是48,这个48是 TextTable 结构的大小

TextTable 结构的大小也就是下图红框位置

然后鼠标单击x96dbg的内存窗口,然后按ctrl+g,然后输入地址,然后点确定转到

然后发现它还不是-1,所以它不是最后一个数据

继续找

看到它还不是-1

继续

然后就找到-1了

它的中文是,水系咏唱法术

0x58D6F9D0位置字符串的效果图

然后发现个事情0x7CCFF27C这个位置的值是0x5897B020,但是x96dbg跳过去之后不是了,如下图,是刚开始的地方,x96dbg给我们跳到了0x5897B050位置了,但是找哈希冲突的值也还是上方那样的找发,图都截完了才发现x96dbg给跳错了

TextManger.cpp文件的修改:修改了 LoadTextData函数、ReadTextById函数

#include "pch.h"
#include "TextManger.h"unsigned TextManger::ReadTextProc = 0x10295FB0;
const wchar_t TextManger::NullText[2]{};bool TextManger::CreateTextDat(const char* _filename)
{if (!textTable) {return false;}std::ofstream out(_filename, std::ios::out|std::ios::binary);if (out.bad())return false;out.write((char*)&hashCount, sizeof(hashCount));for (int i = 0; i < hashCount; i++) {// 游戏中的中文表结构是 中文名英文id 这样的int lenId = strlen(textTable[i]->TxtId) + 1;// 宽字节一个字是2字节,wcslen函数返回值是字的个数int lenTxt = wcslen(textTable[i]->Txt) + 1;lenTxt = lenTxt * 2;out.write(textTable[i]->TxtId, lenId);out.write((char*)textTable[i]->Txt, lenTxt);}out.close();return true;
}bool TextManger::LoadTextData(const char* _filename)
{CString txt;if (textDatas)return false;std::ifstream file(_filename, std::ios::in | std::ios::binary|std::ios::ate);if(file.bad()) {return false;}unsigned buffSize = file.tellg();TextBuff = new char[buffSize];file.seekg(std::ios::beg);file.read(TextBuff, buffSize);// textTable = new PTextTable[Count[0]];textDatas = new TextTable[Count[0]];txt.Format(L"%X", &textDatas);AfxMessageBox(txt);char* buffStart = TextBuff + 4;char* buffEnd = buffStart + buffSize;int icount = 0;while(buffStart < buffEnd){// 读取语言文件的数据到 textDatas 变量里int lenId = strlen(buffStart) + 1;memcpy(textDatas[icount].TxtId, buffStart, 0x24);buffStart = buffStart + lenId;int lenTxt = wcslen((wchar_t*)buffStart) + 1;lenTxt = lenTxt * 2;textDatas[icount].Txt = (wchar_t*)buffStart;buffStart = buffStart + lenTxt;icount++;}hashCount = Count[0];HashIndexTable = new unsigned[hashCount];memset(HashIndexTable, 0xFF, hashCount * sizeof(unsigned));for (int i = 0; i < Count[0]; i++) {// 给 textDatas 变量添加哈希算法索引(哈希表存放 textDatas的下标)unsigned hash = Hashcode(textDatas[i].TxtId);hash = hash % (hashCount + 1);if (HashIndexTable[hash] == -1) {HashIndexTable[hash] = i;}else {PTextTable nullTable = GetNullText(&textDatas[HashIndexTable[hash]]);nullTable->next = i;}}return false;
}const wchar_t* TextManger::ReadTextById(const char* _id)
{// unsigned callProc = 0x10295FB0;if (textTable) {int index;_asm {push ebxmov ebx, thispush _idcall ReadTextProcmov index, eaxpop ebx}if (index < 0)return NullText;PTextTable* _table = textTable;return (wchar_t*)_table[index]->Txt;}else {unsigned hash = Hashcode(_id);hash = hash % (hashCount + 1);unsigned index = HashIndexTable[hash];if (index > hashCount) {// index的值如果是-1那么它肯定比hashCount大return NullText;}while (strcmp(textDatas[index].TxtId, _id)) {index = textDatas[index].next;if (index > hashCount)return NullText;}return textDatas[index].Txt;}
}unsigned TextManger::Hashcode(const char* id)
{unsigned hash = 0;for (int i = 0; id[i]; i++){hash = hash * 131 + id[i];}return hash;
}PTextTable TextManger::GetNullText(PTextTable _table)
{while (_table->next != -1) {// 从链表中找出最后一个(next的值是-1的)_table = &textDatas[_table->next];}return _table;
}

TextManger.h文件的修改:修改了 TextTable结构体

#pragma once
#include <iostream>
#include <fstream>/*
03E1B73B | 68 58120304              | push fxgamelogic.4031258         | 4031258:"gui"
03E1B740 | E8 7BEF0F00              | call fxgamelogic.3F1A6C0         |
03E1B745 | 83C4 04                  | add esp,4                        |
03E1B748 | 85C0                     | test eax,eax                     |
03E1B74A | 0F84 10090000            | je fxgamelogic.3E1C060           |
03E1B750 | 68 4C120304              | push fxgamelogic.403124C         | 403124C:"TextManager"
03E1B755 | 50                       | push eax                         |
03E1B756 | 8D4C24 64                | lea ecx,dword ptr ss:[esp+64]    |
03E1B75A | 51                       | push ecx                         |
03E1B75B | E8 00091000              | call fxgamelogic.3F1C060         |
03E1B760 | 8D5424 68                | lea edx,dword ptr ss:[esp+68]    |
03E1B764 | 52                       | push edx                         |
03E1B765 | E8 16EF0F00              | call fxgamelogic.3F1A680         | 111111111111
03E1B76A | 83C4 10                  | add esp,10                       |
03E1B76D | 85C0                     | test eax,eax                     |
03E1B76F | 894424 14                | mov dword ptr ss:[esp+14],eax    | [esp+14]:CD3DDDIDX10_DrawIndexedPrimitive+113
*/
// 游戏中的中文表结构是 中文名英文id 这样的
typedef class TextTable {
public:int next = ((int)0xFFFFFFFF);int un = sizeof(TextTable);wchar_t* Txt;// 中文char TxtId[0x24];// 中文对应的英文id
}*PTextTable;typedef class TextManger
{
public:static unsigned ReadTextProc;static const wchar_t NullText[2];
private://int un[0x20];// 0x20 * 0x4 = 0x80int un[0x1E];union {char* TextBuff;unsigned* Count;};PTextTable textDatas = nullptr; // 中文结构
public:PTextTable* textTable = nullptr; // 暂时无用
private:int un1;
public:unsigned hashCount;unsigned* HashIndexTable = nullptr; // 哈希表
public:bool CreateTextDat(const char* filename); // 导出语言包bool LoadTextData(const char* _filename); // 加载 CreateTextDat函数写出的文件const wchar_t* ReadTextById(const char* _id); // 根据id获取中文名unsigned Hashcode(const char* id);// 哈希函数// 获取一个未使用的中文与对应id结构,用与存放从文件中读取的中文与对应idPTextTable GetNullText(PTextTable _table);
}*PTextManger;

CUIWnd_0.cpp文件的修改:修改了 OnBnClickedButton2函数

// CUIWnd_0.cpp: 实现文件
//#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_0.h"
#include "afxdialogex.h"
#include "extern_all.h"
#include "GameOBJECTDef.h"// CUIWnd_0 对话框
float _xNext = 0.0f;
float _yNext = 0.0f;
void _stdcall loops(HWND, UINT, UINT_PTR, DWORD) {PAIM aim = Client->GetAimByName(L"r");if (aim == nullptr) {return;}//AfxMessageBox(aim->Name);float xDis = fabs(Client->Player.x - aim->x);float hDis = fabs(Client->Player.h - aim->h);float yDis = fabs(Client->Player.y - aim->y);float xNext, yNext, thisx, thisy;int v[2]{ -1, 1 };if (xDis > 12) {// 强制修改角色x坐标的值thisx = Client->Player.x;Client->Player.x = Client->Player.x + 6 * v[Client->Player.x < aim->x];xNext = Client->Player.x;}else {xNext = aim->x;}if (yDis > 12) {// 强制修改角色y坐标的值thisy = Client->Player.y;Client->Player.y = Client->Player.y + 6 * v[Client->Player.y < aim->y];yNext = Client->Player.y;}else{yNext = aim->y;}if ((xDis < 2)&&(hDis < 2)&&(yDis < 2)) {Client->MoveStop(aim->x, aim->h, aim->y, 0.0f);}else {Client->MoveWalk(Client->Player.x,aim->h, Client->Player.x, 0.0f, 0.0f, xNext, yNext);}
}IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)CUIWnd_0::CUIWnd_0(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_PAGE_0, pParent)
{}CUIWnd_0::~CUIWnd_0()
{
}void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_0::OnBnClickedButton1)ON_BN_CLICKED(IDC_BUTTON2, &CUIWnd_0::OnBnClickedButton2)
END_MESSAGE_MAP()// CUIWnd_0 消息处理程序void CUIWnd_0::OnBnClickedButton1()
{// 发送坠落数据包//Client->Fall();设置移动速度float Speed = 30.0;Client->SetProperty(Client->Player.lId, INDEX_MoveSpeed, &Speed);/*// 修改血量int HP = 10000000;Client->SetProperty(Client->Player.lId, INDEX_HP, &HP);*//*CString txt;txt.Format(L"通过AIM类获取角色信息 名字:%s,x坐标:%f", Client->Player.Name, Client->Player.x);AfxMessageBox(txt);*/// Client->HeartBeep();// Client->TalkTo(L"r", L"打架吗?");// Client->Talk(L"[欢迎来到麟科思]");// Client->SelectRole(L"今晚打老虎");/*Client->CreateRole(L"am4", 1.0, 2.0, 4.0, 8.0, "gui\BG_team\TeamRole\Teamrole_zq_humF_001.PNG","Face,0;Hat,0;Eyes,0;Beard,0;Ears,0;Tail,0;Finger,0;Cloth,0;Pants,0;Gloves,0;Shoes,0;Trait,0;HairColor,0;SkinColor,0;SkinMtl,0;Tattoo,0;TattooColor,16777215;","", 0.0);*///Client->SelectCamp("xuanrenZQ");//Client->StartCreateRole();//Client->DelRole(L"ranzhi11111");/*char buff[] = {0xA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 00 ,0x00,0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x31, 0x00, 0x32 ,0x00,0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};WinSock->OnSend(buff, sizeof(buff));*//*char buff[] = {0x27, 0x46, 0x92, 0x02, 0x00, 0x00, 0x89, 0x02, 0x00, 0x00, 0x06, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x74, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x0A, 0x00, 0x00, 0x00, 0x34, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x00, 0x00, 0x07, 0x5A, 0x02, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00};WinSock->OnRecv(buff, sizeof(buff));*/
}TextManger txtMangerMain;
void CUIWnd_0::OnBnClickedButton2()
{// 根据语言表获取文字//CString txt = txtManger->ReadTextById("npc_GRZJ_0001");// PGameProc->GetTextName("npc_GRZJ_0001");//AfxMessageBox(txt);//txtManger->CreateTextDat("F:\\语言包.txt");// 读取导出到本地的语言包txtMangerMain.LoadTextData("F:\\语言包.txt");// CString txt = txtMangerMain.ReadTextById("npc_GRZJ_0001");// npc_GRZJ_0001没有哈希冲突/* Hui_event_3_1有哈希冲突,通过打印 textDatas 变量的内存地址去x96db找的(第一个就冲突了,ui_event_3_1是第一个哈希表里的链表的最后一个)如果第一个没有冲突,那就找一个 next 不是 -1 的,不是-1说明是链表,然后找链表最后一个就可以了*/CString txt = txtMangerMain.ReadTextById("ui_event_3_1");AfxMessageBox(txt);txt = txtMangerMain.ReadTextById("desc_Item_A550001_01_2");AfxMessageBox(txt);// 瞬移//float decX = 3843.776123f;//float decH = 11.731983f;//float decY = -2005.533813f;//float face = 0.0f;//Client->Teleport(decX, decH, decY, face);//PAIM aim = Client->GetAimByName(L"r");//if (aim == nullptr) {//	return;//}//Client->Teleport(aim->x, aim->h, aim->y, aim->face);// 修正坐标/*PAIM aim = Client->GetAimByName(L"r");if (aim == nullptr) {return;}Client->SetCoord(Client->Player.lId, aim->x, aim->h, aim->y, aim->face);*/// 面向// Client->FaceTo(L"r");// 飞天// Client->HideMode = true;// 遁地//Client->MoveStop(Client->Player.x, Client->Player.h - 5, Client->Player.y, 0.0f);// 跟随// ::SetTimer(m_hWnd, 0x1000, 2000, loops);// // Client->Backtoroles();
}

相关文章:

  • Typescript高级: 深入理解工厂函数类型
  • 【计算机毕业设计】基于SSM++jsp的实验室耗材管理系统【源码+lw+部署文档】
  • Day02:LeedCode977. 有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II
  • 《Qt》使用Windeployqt发布程序
  • 【yolo 项目】
  • el-radio-group 选择一个,全部选中 解决方案
  • [蓝桥杯 2020 省 A1] 超级胶水
  • 顶顶通呼叫中心中间件-自动外呼输入分机号(比如隐私号)(mod_cti基于FreeSWITCH)
  • 信息泄露--注意点点
  • AI大模型应用开发实践:3.使用 tiktoken 计算 token 数量
  • SQL 面试系列(一)【留存率问题】
  • 【论文笔记】Attention is All You Need(NIPS’17)
  • 递增链表去重
  • 【WEEK13】 【DAY3】Shiro第三部分【中文版】
  • SSL证书制作及nginx部署
  • 07.Android之多媒体问题
  • 2017-09-12 前端日报
  • Android交互
  • docker-consul
  • gcc介绍及安装
  • MySQL用户中的%到底包不包括localhost?
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • uni-app项目数字滚动
  • 爱情 北京女病人
  • 我有几个粽子,和一个故事
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ### RabbitMQ五种工作模式:
  • #define
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (正则)提取页面里的img标签
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net FrameWork简介,数组,枚举
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • :O)修改linux硬件时间
  • @Documented注解的作用
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • [ NOI 2001 ] 食物链
  • []error LNK2001: unresolved external symbol _m
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [Excel VBA]单元格区域引用方式的小结
  • [ffmpeg] x264 配置参数解析