请问如何获取游戏中的汉字信息? 200分相送(200分)

  • 主题发起人 主题发起人 16cy
  • 开始时间 开始时间
1

16cy

Unregistered / Unconfirmed
GUEST, unregistred user!
一直有一个问题搞不清楚,就是如何才能获取游戏窗口中的汉字。<br>比如,大话西游II里,经常会有跑环任务、帮派任务等,在游戏中按“ALT+Q”就会弹出一个窗口,里面会显示当前游戏人物的任务,那么我如何才能编程把这些任务读取出来?<br>本人是初学者,请附源码说明,我仅有的200分相送!!!
 
晕,难道没有人会吗?高手啊给点指导啊
 
原理就是用反编译软件如OllyICE截取,先学学汇编先吧
 
楼上的说的这么不清楚啊,都说了我是初学者,要详细点嘛!
 
就凭你说话的口气,就算有高手也懒得理你!
 
去找开发游戏的公司
 
基本上是不可能的.
 
什么我这个菜鸟都知道。。<br> &nbsp;图像,文字识别。。如果是中文可以识别到100%<br> &nbsp;如果做游戏,直接封装CONTENT的类。。。<br><br>其他的自己想吧,,其实许多问题,都有办法解决,但是合适不合适 另外说。
 
图像识别有很大难度吧 要识别多种大小何字体还是很有难度的<br>给楼主找了一篇关于屏幕取词的文章希望对您有帮助<br>不过这种方法只对直接输出文字的有效,对于在图形里用画笔画一个文字出来的就不能识别了<br><br>鼠标屏幕取词技术的原理和实现<br> &nbsp;“鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在windows系统中实现却是非常复杂的,总的来说有两种实现方式:<br> &nbsp; &nbsp;第一种:采用截获对部分gdi的api调用来实现,如textout,textouta等。<br> &nbsp; &nbsp;第二种:对每个设备上下文(dc)做一分copy,并跟踪所有修改上下文(dc)的操作。 &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp;第二种方法更强大,但兼容性不好,而第一种方法使用的截获windowsapi的调用,这项技术的强大可能远远超出了您的想象,毫不夸张的说,利用windowsapi拦截技术,你可以改造整个操作系统,事实上很多外挂式windows中文平台就是这么实现的!而这项技术也正是这篇文章的主题。<br> &nbsp; &nbsp;截windowsapi的调用,具体的说来也可以分为两种方法:<br> &nbsp; &nbsp;第一种方法通过直接改写winapi 在内存中的映像,嵌入汇编代码,使之被调用时跳转到指定的地址运行来截获;第二种方法则改写iat(import address table 输入地址表),重定向winapi函数的调用来实现对winapi的截获。<br> &nbsp; &nbsp;第一种方法的实现较为繁琐,而且在win95、98下面更有难度,这是因为虽然微软说win16的api只是为了兼容性才保留下来,程序员应该尽可能地调用32位的api,实际上根本就不是这样!Win 9x内部的大部分32位api经过变换调用了同名的16位api,也就是说我们需要在拦截的函数中嵌入16位汇编代码!<br> &nbsp; &nbsp;我们将要介绍的是第二种拦截方法,这种方法在win95、98和nt下面运行都比较稳定,兼容性较好。由于需要用到关于windows虚拟内存的管理、打破进程边界墙、向应用程序的进程空间中注入代码、pe(portable executable)文件格式和iat(输入地址表)等较底层的知识,所以我们先对涉及到的这些知识大概地做一个介绍,最后会给出拦截部分的关键代码。<br> &nbsp; &nbsp;先说windows虚拟内存的管理。Windows9x给每一个进程分配了4gb的地址空间,对于nt来说,这个数字是2gb,系统保留了2gb到 4gb之间的地址空间禁止进程访问,而在win9x中,2gb到4gb这部分虚拟地址空间实际上是由所有的win32进程所共享的,这部分地址空间加载了共享win32 dll、内存映射文件和vxd、内存管理器和文件系统码,win9x中这部分对于每一个进程都是可见的,这也是win9x操作系统不够健壮的原因。Win9x中为16位操作系统保留了0到4mb的地址空间,而在4mb到2gb之间也就是win32进程私有的地址空间,由于每个进程的地址空间都是相对独立的,也就是说,如果程序想截获其它进程中的api调用,就必须打破进程边界墙,向其它的进程中注入截获api调用的代码,这项工作我们交给钩子函数(SetWindowsHookEx)来完成,关于如何创建一个包含系统钩子的动态链接库,《电脑高手杂志》在第?期已经有过专题介绍了,这里就不赘述了。所有系统钩子的函数必须要在动态库里,这样的话,当进程隐式或显式调用一个动态库里的函数时,系统会把这个动态库映射到这个进程的虚拟地址空间里,这使得dll成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈,也就是说动态链接库中的代码被钩子函数注入了其它gui进程的地址空间(非gui进程,钩子函数就无能为力了),当包含钩子的dll注入其它进程后,就可以取得映射到这个进程虚拟内存里的各个模块(exe和dll)的基地址,如:<br>hmodule hmodule=GetModuleHandle(“mypro.exe”);<br>在mfc程序中,我们可以用afxgetinstancehandle()函数来得到模块的基地址。Exe和dll被映射到虚拟内存空间的什么地方是由它们的基地址决定的。它们的基地址是在链接时由链接器决定的。当你新建一个win32工程时,vc++链接器使用缺省的基地址0x00400000。可以通过链接器的base选项改变模块的基地址。Exe通常被映射到虚拟内存的0x00400000处,dll也随之有不同的基地址,通常被映射到不同进程的相同的虚拟地址空间处。<br> &nbsp; &nbsp;系统将exe和dll原封不动映射到虚拟内存空间中,它们在内存中的结构与磁盘上的静态文件结构是一样的。即pe (portable executable) 文件格式。我们得到了进程模块的基地址以后,就可以根据pe文件的格式穷举这个模块的image_import_descriptor数组,看看进程空间中是否引入了我们需要截获的函数所在的动态链接库,比如需要截获“textouta”,就必须检查“gdi32.dll”是否被引入了。说到这里,我们有必要介绍一下pe文件的格式,如右图,这是pe文件格式的大致框图,最前面是文件头,我们不必理会,从pe file optional header后面开始,就是文件中各个段的说明,说明后面才是真正的段数据,而实际上我们关心的只有一个段,那就是“.idata”段,这个段中包含了所有的引入函数信息,还有iat(import address table)的rva(relative virtual address)地址。<br> &nbsp; 说到这里,截获windowsapi的整个原理就要真相大白了。实际上所有进程对给定的api函数的调用总是通过pe文件的一个地方来转移的,这就是一个该模块(可以是exe或dll)的“.idata”段中的iat输入地址表(import address table)。在那里有所有本模块调用的其它dll的函数名及地址。对其它dll的函数调用实际上只是跳转到输入地址表,由输入地址表再跳转到dll真正的函数入口。<br><br> &nbsp; &nbsp;具体来说,我们将通过image_import_descriptor数组来访问“.idata”段中引入的dll的信息,然后通过image_thunk_data数组来针对一个被引入的dll访问该dll中被引入的每个函数的信息,找到我们需要截获的函数的跳转地址,然后改成我们自己的函数的地址……具体的做法在后面的关键代码中会有详细的讲解。<br> &nbsp; &nbsp;讲了这么多原理,现在让我们回到“鼠标屏幕取词”的专题上来。除了api函数的截获,要实现“鼠标屏幕取词”,还需要做一些其它的工作,简单的说来,可以把一个完整的取词过程归纳成以下几个步骤:<br>1. 安装鼠标钩子,通过钩子函数获得鼠标消息。<br> &nbsp; &nbsp;使用到的api函数:setwindowshookex<br>2. 得到鼠标的当前位置,向鼠标下的窗口发重画消息,让它调用系统函数重画窗口。<br> &nbsp; &nbsp;使用到的api函数:windowfrompoint,screentoclient,invalidaterect<br>3. 截获对系统函数的调用,取得参数,也就是我们要取的词。<br><br> &nbsp; &nbsp;对于大多数的windows应用程序来说,如果要取词,我们需要截获的是“gdi32.dll”中的“textouta”函数。
 
图像识别?<br>因为我不认为抓词可以抓游戏的画布。
 
屏幕取词根本不能实现这个的。。。。。<br>我看只有用图像识别了吧,汗。。。<br>因为游戏中的坐标是随时变化的,不可能抓下来。<br><br>这个游戏的坐标可以用单机游戏修改工具查到内存中的地址,可是每次更换游戏场景,这个坐标在内存中的地址就会变化。<br><br>我想是不是在内存里面也能找到游戏中的汉字?
 
我想是不是在内存里面也能找到游戏中的汉字? &nbsp;<br><br>--------------<br>一定可以。只是你不知道它保存在哪里
 
可以把当前的句柄找出来,再用把里面的控件用回调方法一个一个找出来。<br>然后读出来不就行了。。。
 
可以通过读取内存或HOOK API实现
 
来自:hzjone, 时间:2006-8-5 8:07:44, ID:3525936<br>可以把当前的句柄找出来,再用把里面的控件用回调方法一个一个找出来。<br>然后读出来不就行了。。。 &nbsp;<br><br><br>来自:中国最猥琐的程序员, 时间:2006-8-5 8:19:45, ID:3525939<br>可以通过读取内存或HOOK API实现 &nbsp;<br><br>楼上的两位,可不可以给一段具体的代码???我刚学delphi不到一个月,55555
 
Hook Textout API
 
个人人为屏幕取词是比较好的做法<br>当然 这种做法有可能不能取到对应的字<br>例如早期的有些游戏并非用标准字库中的字,而是自己有一套字库的,我记得早先的仙剑奇侠就是这样的。<br>如果是使用标准字库的字 并且通过canvas的textout画出来的就都可以用屏幕取词的方法获得。<br>简单说就是hook Textout Api<br>楼主说的字的坐标变化并不是问题,因为坐标变化必然会导致重画事件 所以通过hook Textout Api还是可以取到
 
我用过别人的屏幕取词软件,捉不到词,烦!<br>我现在在想,是不是可以通过扫描颜色来区分。<br>首先建立一个数字0-9、游戏人物名的点阵颜色信息文件,然后再扫描特定区域点阵颜色,通过与事先建立的颜色信息文件对比来获取文字。<br>我想应该是可行的!<br>不过不知道速度会不会太慢。
 
我劝楼主在大家还没有发怒的时候去掉标题的最后一句话....
 
高手累了在睡觉[:D]
 
后退
顶部