在大学中 最头疼的两门语言莫过于 C和汇编
汇编语言 C语言难学几乎成了流传
特别是C的指针
实际上理解汇编,C的指针就很好理解了
有人说 不懂C和汇编的不算真正程序员
本文带大家成为 真正程序员
1 认识汇编:
mov eax,1000h
add eax,4000h
sub eax,2000h
call dumpregs
假如说我们是厨师,我们就要了解刀子,汤勺,炉子的用法(怎么老想起染红动画第二话)
汇编不像C,它是和硬件打交道的
CPU有存储单元 叫寄存器,速度快过内存 这个是常识。
基本寄存器:32位汇编
EAX EBP
EBX ESP
ECX ESI
EDX EDI
这些寄存器使用有规则的,具体可以看看汇编的书
另外还有些段寄存器
上面的语句就类似于:
EAX <- 1000h ;mov 是move的助记,相当于拷贝,16进制数尾部都标有H 作为记号
EAX <- (EAX+4000h) ;SUB和ADD是很简单的单词
EAX <- (EAX-2000h)
调用dumpregs 用于显示;自定义的过程、函数
[]和指针
最难的就是这些东西了
大师用个最常见的例子告诉大家:
坑神要给大师个文件,比如 あかね色に染まる坂
坑神一般不直接传,而是上传到FTP或者其他地方
然后给大师给下载链接
好
游戏本体就相当于 数据,而下载链接就是指针,指针其实也是个数,用来存地址
比如
.data
val1 BYTE 10h
.code
mov esi,OFFSET val1;val1的地址 -〉esi
mov AL,[esi] ;将esi的数据作为 地址,找该地址的数据,ESI数据假如是5000H地址,那么把内存地址为5000H的数据-〉AL ,而指针就是ESI,地址是5000H
示例:
int _tmain(int argc, _TCHAR* argv[])
{
int a,b=0;
a=43;
b=a;
return 0;
}
在VC++ 中设置断点
然后选择查看汇编窗口
int a,b=0;
013717CE mov dword ptr [b],0
a=43;
013717D5 mov dword ptr [a],2Bh
b=a;
013717DC mov eax,dword ptr [a]
013717DF mov dword ptr [b],eax
return 0;
013717E2 xor eax,eax
}
013717
断点是什么?
排练的时候教练会叫大家 : 停
然后指出问题后继续
断点就是 让程序停在那里,咱们可以仔细研究
这是研究程序很重要方法
013717CE mov dword ptr [b],0
这是什么意义?
dword ptr 是伪指令,人们发现光Intel CPU指令还是不行,比如要定义数据大小的指令都没有,所以我们的编译器(老师应该说过,比如MASM,VC++)都会有自己可以识别但不是
Intel CPU指令的指令
dword 是一种数据类型,dword Ptr 就是正版的定义指针 指向内存
上面的那句相当于
b本身是个指针
先读b 找到地址
把地址存的数据再作为指针
最后把0 送到 目标内存地址
把上面两句话合一了
其实就是一个功能 把0-〉目标内存地址
你肯定会说,怎么那么麻烦
直接
mov [b],0
试试看
mov [b],0 可以吗?为什么?
用刚才的例子: 坑神姐姐认为论坛FTP不方便,于是就上传网盘,然后给大师下载地址
此时无法直接下载的,网盘有防盗链系统。
我的闲话: 汇编考完试,常听徒弟说,那啥,指令太多了,忙不过来。我就很奇怪,我做试卷的时候反而发现指令不多啊,就那么几条。。。。。。
实际上,真正用到的指令确实不多,所以有人提出RISC和CISC之争。
现在打开调试器,大家会发现,无从下手
为什么呢?就像游戏一样,最终BOSS都不知道,怎么开战?
还有人问: 大师,你昏了吧,又不叫你输CDKEY ,破解了干什么?
galgame 游戏汉化和galgame 游戏翻译入门经典教程
提到,区位码问题,直接灌中文会乱码
API是什么?
搞C/C++编程,必须掌握API
类似这样的语句大家见过吧:
cout<<endl
cout 就是C++函数,是C++系统提供的
同样我们要搞windows开发,必定用到windows提供的函数,只不过换个名字
API(Application Programming Interface,应用程序编程接口)
染红必定使用了字体的API我们的任务就是修改这个函数
MSDN 是什么?
微软给我们的电子字典,英语不懂查朗文或者牛津,程序要查MSDN
想想看创造字体的函数会叫啥?
启动MSDN(也可以去在线网站)
找到下面函数:
HFONT CreateFont(
int nHeight, // height of font
int nWidth, // average character width
int nEscapement, // angle of escapement
int nOrientation, // base-line orientation angle
int fnWeight, // font weight
DWORD fdwItalic, // italic attribute option
DWORD fdwUnderline, // underline attribute option
DWORD fdwStrikeOut, // strikeout attribute option
DWORD fdwCharSet, // character set identifier
DWORD fdwOutputPrecision, // output precision
DWORD fdwClipPrecision, // clipping precision
DWORD fdwQuality, // output quality
DWORD fdwPitchAndFamily, // pitch and family
LPCTSTR lpszFace // typeface name
);
有时候 视野要看开,比如 下面这段信息是EnumFontFamiliesEx 内容,却很重要
The EnumFontFamiliesEx function enumerates all fonts in the system that match the font characteristics specified by the LOGFONT structure. EnumFontFamiliesEx
enumerates fonts based on typeface name, character set, or both.
To get the appropriate font on different language versions of the OS, call EnumFontFamiliesEx with the desired font characteristics in the LOGFONT structure,
retrieve the appropriate typeface name, and create the font using CreateFont or CreateFontIndirect.
估计大家看E文很浮云,但是一个真正的程序员E文必须很好
上面
EnumFontFamiliesEx就是初始化 选择字体的函数,告诉程序有那些字体可用,CreateFont 用来创造字体
其中也包括 character set
这些就是要修改的 BOSS
总的来说就是要修改程序的 CreateFont 或者CreateFontIndirect 还有EnumFontFamiliesEx
将character set 改为 中文,这样染红就可以显示中文了
查资料
DWORD fdwCharSet, // character set identifier
字符集 值
ANSI_CHARSET 0
DEFAULT_CHARSET 1
SYMBOL_CHARSET 2
MAC_CHARSET 77
SHIFTJI_CHARSET 128 日文
HANGEUL_CHARSET 129
HANGUL_CHARSET 129
JOHAB_CHARSET 130
GB2312_CHARSET 134 简体中文
CHINESEBIG5_CHARSET 136 繁体中文
GREEK_CHARSET 161
TURKISH_CHARSET 162
VIETNAMESE_CHARSET 163
HEBREW_CHARSET 177
ARABIC_CHARSET 178
BALTIC_CHARSET 186
RUSSIAN_CHARSET 204
THAI_CHARSET 222
EASTEUROPE_CHARSET 238
OEM_CHARSET 255
一般来说汇编用16进制数据,记不记得上面汇编也是16进制
简单地说,要使程序能正常使用中文,就是要把程序中字符集的值由80改成0x86或者0x88(繁体),
提示:16进制数转换用 计算器
由于在Vista 下那个所谓的OllyDebug汉化 无非用,我找了 OllyICE
OllyICE是爱好者继续开发OllyDebug的东西,也是换个名字,都差不多