Dungeon Siege 3 *.OAF 格式分析
探索未知事物,比玩游戏本身要有趣的多。
上一篇提到,有一些现成的工具可以用来提取、压缩OAF文件,不过还是想对文件结构能有更精确的了解。经过一番分析,有了以下结果,不过仍有部分未知,有待继续研究。
DS3的OAF文件基本可以分为四部分:file header, zlib stream offset table, zlib stream, file name and tree structure table
1). File header. 文件头。
0×0: 3 bytes. 即被称为magic number或者signature的部分,’OAF’
0×3: 9 bytes. 未知。当然这一部分也可能是文件签名的一部分。
0xC: 4 bytes. File name table entry offset. 保存文件名表的入口偏移。
0×10: 4 bytes. 未知。
0×14: 4 bytes. Entry number,表项数目。zlib数据流包含的压缩包数目应该与文件名数目相等,否则无法匹配。
0×18: 4 bytes. 未知。感觉像是某种校验。
2). Zlib stream offset table. zlib数据流偏移表。
每个表项都指向文件中具体一个压缩包的未知,表项长度为0×14个byte。容易算出来,这部分的长度应该是 0×14 bytes * 表项数,出于对齐的考虑,这部分结束后可能有若干字节补零。
每个表项的结构如下:
0×0: 4 bytes. zlib压缩包起始偏移。
0×4: 4 bytes. 未知。感觉上可能是与压缩算法有关的参数。
0×8: 4 bytes. Raw data size. 未压缩数据的大小。
0xC: 4 bytes. Packed data size. 压缩后数据的大小。如果为0则说明这一表项指向的数据没用压缩。
0×10: 4 bytes. 未知。感觉有可能是未压缩数据的某种校验。
3). Zlib stream. zlib数据流。
这一部分的起始地址应该是0×10 byte对齐的,即”起始地址 & 0xF = 0″。
根据第二部分的每一个表项,都可以在这部分中找到对应的、压缩后的数据流。
4). File name and tree structure. 文件名和目录结构。
该部分的偏移在文件头中有描述。
这部分是若干个字符串,每个字符串都有标准结尾”0×0″. 文件名和第二、三部分按照相同的次序排列,一一对应。
有了以上这些信息,接下来准备做一个提取用的工具,顺便也玩一下zlib。另外,未知的部分也要想办法研究一下。
Dungeon Siege 3 初体验及相关工具
从DS1的喜欢,到DS2的迷恋,到3代出来,真的好久了。
DS最先吸引住人的应该是其背景音乐,宏大的场面,昂扬的斗志,以及世界的奇幻,每个人都能在一遍又一遍重复的音乐中找到那种感觉。
其次就是其扩展性极强的mod系统,给游戏带来了更多变化和乐趣。当时自己痴迷其中,也制作/修改了几个mod相关的工具。
等3代的推出等了好久,现在出来了,玩了一把,却有少许失望。
音乐并没有很引人入胜,没有感觉。
虽是Obsidian制作,不过没有了前2代那种感觉,更多的融入了黑曜石自己历代作品的想法。也可能是Square Enix发行的关系,觉得欧美的感觉不正统,而是带上了日式欧美的影子。
不知道是否支持Mod,只看到一定会有DLC,但系统来看mod是不太可能支持了。
画面还是不错的,华丽了很多。不过本人玩游戏对画面并不太重视。
说一说相关工具。大概是沿袭了2代的体会,第一时间就去找相关工具,找到的相关资源如下。不难找所以就不放链接了。
DungeonSiege3Extractor – Raptor的解包工具 DungeonSiege3Translator – Raptor的翻译工具 offzip – Luigi Auriemma的通用解包工具,适用于从偏移提取压缩文件 packzip – Luigi Auriemma的注入工具,与offzip配套使用
使用说明: Extractor可以打开*.oaf的压缩档并提取内容。 比如data_localized_vo_en.oaf,可以发现是英文的全称语音,ogg格式。 比如data_localized_en.oaf,游戏中用到的字符串,比如gui.std和oei_shared_gui.std基本就是所有界面相关的字符串了,呵呵。不过只是这样简单改一下是不能汉化的,还有code page的问题,想办法研究一下。 Translator,方便解析std文件进行字符串修改。 offzip,从指定offset提取有效zip压缩包的工具。用-s参数查看oaf的偏移,可以得到和extractor相同的结果。 packzip,把修改过的文件inject到oaf中,也就是patch。
不管怎么说,总还是很喜欢的作品,耐心打完再谈体会吧。
M50创意园
其实我不懂艺术的。我和艺术唯一沾边的大概就是听听古典音乐了吧。
沿着莫干山路尽头的涂鸦巷一路走进去,除了各种涂鸦风格的不同之外,感觉也是随之变化的,从城市角落的破马路,到硬朗的厂房,再到残破的待拆小楼,最后到一个很具现代气息的创意园入口。颇有意思的是,残破小楼周围有着广场上那种广播,看着,听着,非常有五、六十年代的那种感觉。其实那声音来自对面的垃圾房,里面放着的广播产生了极好的共鸣。不太协调的是对面住宅小区外有很多中档车,略破坏气氛。
阴天,小雨,这种天气还挺适合逛艺术之地的。
改造后的厂房,只有留下的管道和墙上的铭牌告诉我们这里曾经是什么,除此之外,就是各种装饰风格的工作室、展览室。颜色和线条都很简单,不同的作品让你感觉到,主人有不同的风格。当然还有一点是共同的:玻璃门上贴着的银联标记。
两个多小时,大概看了1/4不到的地方吧。油画、摄影、雕塑,还有其他艺术品,都看了一些。想不出很多词汇来描述,作者用各种熟悉的手段,来表现自己内心追求的一种想法,或者一种意识形态。其实并不难明白有些作品表达的意思,作品中的元素有时候是很简单的。只是很难明白,他们选择用这样一种方式表达一些东西的过程。大概这就是我们和搞艺术的人的区别吧:思维方式。
很多门没敢去推开。。。因为里面没有人,怕一眼就看出来自己不懂进去瞎逛。听说这是摩羯男爱面子!= =!
偶尔也装一回文青,体会些东西。
Windows密码验证之MsvpPasswordValidate
Title: Windows密码验证之MsvpPasswordValidate
Author: Colin.Xu@gmail.com
Date: 2011/02/24
在codeproject.com闲逛,看到捷克人fhrdina写的一篇有趣的文章。
http://www.codeproject.com/KB/security/Bootkit.aspx
在windows用户登陆界面输入密码后,Local Security Authentication Server(lsass.exe)会做用户密码的校验,模块msv1_0.dll中的msv1_0!MsvpPasswordValidate会做密码的hash比较。所以最简单有效的办法是,只要brute force该函数比较成功,则登陆时就会以为密码校验成功。
这个方法在06年就被人发现了,http://www.rootkit.com/blog.php?newsid=549. fhrdian做了一个可启动的iso,通过在load msv1_0.dll时hook上去,然后patch了它的IAT,把用于hash值比较的函数RtlCompareMemory指向了自己定义的函数,从而使得密码校验永远能够成功。
看完文章后我试了一下win7,发现该方法仍然有效。
来看一下函数原型:
msv1_0!MsvpPasswordValidate (unsigned char, _NETLOGON_LOGON_INFO_CLASS, void *, struct _USER_INTERNAL1_INFORMATION *, unsigned long *, struct _USER_SESSION_KEY *, struct _CLEAR_BLOCK *)
关键部分:
77c798a4 ff153012c777 call dword ptr [msv1_0!_imp__RtlCompareMemory (77c71230)]
77c798aa 83f810 cmp eax,10h
77c798ad 7511 jne msv1_0!MsvpPasswordValidate+0×94 (77c798c0)
;这里,发现hash正确的话,就直接返回了,eax=1,表示校验成功。
;如果不正确,跳到msv1_0!MsvpPasswordValidate+0×94去做其他事情。
77c798af b001 mov al,1
77c798b1 8b4dfc mov ecx,dword ptr [ebp-4]
77c798b4 5f pop edi
77c798b5 5e pop esi
77c798b6 5b pop ebx
77c798b7 e80182ffff call msv1_0!__security_check_cookie (77c71abd)
77c798bc c9 leave
77c798bd c21c00 ret 1Ch
我试着patch了一下msv1_0.dll,然后替换上去,输入任何密码都能进系统了。不过不清楚这样做了之后,user security token以及EFS加密后的数据是否能够访问。如果用户密码的校验最后都在这里完成的话,似乎也太弱了一些。
CMD Prompt Can be Full Screen Again in Windows 7?! – An Explanation of Why Windows 7 Doesn’t Support CMD Prompt Full-Screen Mode and an Issue Analysis.
Title: CMD Prompt Can be Full Screen Again in Windows 7?! – An Explanation of Why Windows 7 Doesn’t Support CMD Prompt Full-Screen Mode and an Issue Analysis.
Author: Colin.Xu@gmail.com
Date: 2011/02/17
Recently my colleague found an interesting phenomenon in Windows 7, sometimes the cmd prompt (dos command window) can be switched to full-screen mode by pressing ALT+Enter. You can easily reproduce this issue by simply disable and re-enable you display adapter. After restarting, all backs to normal: a message box will pop up and notify you that the full-screen mode is not supported.
Many users may already know that ALT+Enter is a commonly used hotkey to switch application between window mode and full-screen mode. For the cmd prompt, the hotkey should work as expected on prior windows OS before windows XP. But for Windows Vista and Windows 7, cmd shouldn’t be switched to full-screen mode, this is by design. If you know some workaround to switch cmd to full-screen, please be patient to read the following analysis first. Then I’ll tell you some known “workaround”.
After the display driver is installed and enabled properly, OS will pass all the desktop resolution changes to driver, then driver will manipulate the graphics adapter to output the desired video signal to monitor. But when display driver is disabled or in dos full-screen mode, the resolution change is not handled by driver anymore. The VGA driver of OS (VGA.SYS) will pass all mode change request to VBIOS via interrupt call (INT 10), then VBIOS will program the graphics adapter. In XDDM (Windows XP Display Driver Model, adopted in Windows 2000 and Windows XP), INT 10 communications between OS and Video BIOS is permitted. But from WDDM (Windows Display Driver Model, adopted in Windows Vista and Windows 7), INT 10 communication is not allowed because of potential unstable problem. Microsoft suggests using ACPI method. For more detailed explanation, please check
http://www.microsoft.com/whdc/system/platform/firmware/wddm_bios.mspx.
So why cmd can be switched to full-screen after end-user disable and re-enable the display driver? First, we should know how Windows Vista and Windows 7 block the switching, how it works.
1. When user start a cmd prompt, C/S Runtime SubSystem (csrss.exe) will create a Console Window Host process (conhost.exe).
2. During the initialization of conhost.exe, it will initialize some full-screen parameters by calling conhost!InitializeFullScreen() function.
3. Conhost.exe call into kernel space, via win32k!DrvEnumDisplaySettings() function, to get available dos full-screen display device.
In display driver enabled mode, the device should be empty, because in this mode OS doesn’t support full-screen dos.
In display driver disabled mode, the device name is “Video3″, it is the “VGA safe device”, which means in this mode VGA.SYS will handle the resolution change with VBIOS.
If currently it is the VGA driver, (display driver disabled mode), it will “OR” the flag (0×10000000) to conhost!gConsoleInformation.Flags, at the offset 0x10c of structure _CONSOLE_INFORMATION, to indicate that the cmd prompt can be switched to full-screen mode.
If currently there is no VGA driver, (display driver enabled mode), it will “OR” the flag (0×00000000), to indicate that the cmd prompt cannot be switched to full-screen dos.
4. Then user press ALT+Enter hotkey. The conhost!HandleSysKeyEvent thread will catch the key pressing message, and first it will check the conhost!gConsoleInformation, if it supports VGA mode (VBIOS will handle the resolution change).
If it doesn’t support (conhost!gConsoleInformation.Flags doesn’t have 0×10000000 bit), then it will pop up the warning message box.
If it supports (conhost!gConsoleInformation.Flags has 0×10000000 bit), then will switch to full-screen dos (by calling conhost!ConvertToFullScreen()) or back to window mode (conhost!ConvertToWindowed).
In OS kernel, there is a global variable, win32k!gFullscreenGraphicsDevice, to save current dos full-screen display device.
In normal case, display driver enabled mode, win32k!gFullscreenGraphicsDevice is empty. So the switching to full-screen of cmd prompt can be blocked.
After a Stop/Start display device happens, win32k!gFullscreenGraphicsDevice is not cleared, so conhost.exe will think there exists a dos full-screen display device, then the switching to full-screen dos cannot be blocked anymore, but executed.
During Windows boot up, after display driver is enabled, OS will call win32k!DrvUpdateVgaDevice() function to clear win32k!gFullscreenGraphicsDevice.
When disable the display driver, OS will also call this function to update win32k!gFullscreenGraphicsDevice to VGA safe device.
But when enable the display driver again without restarting, win32k!gFullscreenGraphicsDevice is not cleared, it still keeps the previous data, although win32k!DrvUpdateVgaDevice() is also called.
This is why this interesting issue happens.
From the above analysis, such behavior looks like an OS bug. Although I’ve posted the information on MSDN forum, I have not got any definite waiver or KB yet.
All the above analysis is based on reverse engineering by taking depth into ASM, and for the researching purpose only.
Finally, I’ll talk about some know “workaround” to make cmd prompt “full-screen”.
1. Of course, the issue described in this article is a possible way. But since INT 10 communication has some potential unstable problem, you may choose it on your own risk.
2. Install “Windows XP Mode” on Windows 7. This is actually a virtual machine. Since this is officially supported by Microsoft, it will be the best solution.
3. Change the font of cmd prompt and maximize the window. This is a pretty tricky way, isn’t it?
4. Install XDMM driver on Windows 7. I read this method in mydigitallife.info forum. To be honest, I don’t think this is a good solution. WDDM driver should have the best compatibility with Windows Vista and Windows 7. XDDM and WDDM have totally different architecture, and with no doubt, abusing the wrong model will crash the system easily.
5. Disable display driver. Just for running dos in full-screen? Why not install a pure virtual machine or run DosBox?
Hope this article may help you.
Hack Manufacturer Information of Your Computer – An Approach to Remove OEM Limitation When Installing Some Applications
Title: Hack Manufacturer Information of Your Computer – An Approach to Remove OEM Limitation When Installing Some Applications
Author: Colin.Xu@gmail.com
Date: 2011/02/17
Recently I was debugging an application related SW issue, which requires specific HW and SW environment. In order to compare with the expected behavior, I tried to install this application on another system comes from a different OEM. But the install program (install shield) denied to continue the installation, it popped up a message box to notify that the OEM didn’t match. I suppose the install program has a mechanism to limit the packed application can only be installed on specific OEM platforms.
In order to install the application without limitation, I have the following options, from user mode view:
1. Disassemble the install program and remove this OEM detection limitation.
This is not easy and done within short time. Not to mention to detect the pack style, I also need to analyze the install program. Potential workload is too heavy.
If it is a *.MSI package, it will be much easier.
2. Unpack the application and run without installation.
The version of install shield is up-to-date, so utility such as Universal Extractor doesn’t support to extract the application from the encrypted package.
Also, I’m not sure if the extracted application can work normally. Obviously such kind of application needs many registry entries and registered COM components.
I think I should come back to the original problem.
I guess the install program only limit the manufacturer information, but ignore the others, such as sub-system ID. Otherwise, OEM has to build different application installation program for all its platforms, unnecessarily.
In user mode level, application will call EnumSystemFirmwareTables() and GetSystemFirmwareTable() to retrieve information from system firmware, such as BIOS. Then user mode API will pass this call to kernel, kernel will retrieve this information from a global variable, which is initialized at system boot up. Where does OS get the motherboard information? Of course it comes from BIOS.
The data path is: Applicaton-(via API)->OS-(DMI)->BIOS. So what happens if we can cheat the OS with the modified BIOS?
Obviously it is much safer to modify the manufacture information stored in the physical memory then flashing a customized BIOS. OK, Let’s do it.
First, you should know what SMBIOS and DMI stand for. SMBIOS is abbreviation of System Management BIOS, which defines some data structures stored in BIOS to store and retrieve computer information. DMI refers to Desktop Management Interface, which provides an interface for upper level OS to retrieve the hardware information from SMBIOS.
According to x86 design, BIOS is always mapped to a fixed physical memory address, 0xF0000. We search the area ranged from 0xF0000 to 0xFFFFF, to find string begin with “_SM_” and “_DMI_”. It should locate within this region, if your system supports SMBIOS. The “_SM_” is the so-called “anchor string”. The start address of string “_SM_” is the first four bytes of SMBIOS Entry Point Structure, let’s call it Addr_EPS. Go to offset 0x18h (Addr_EPS+0x18h), these stores the 32 bytes big-endian physical address of the SMBIOS Structure Table, Addr_ST. “_DMI_” will only appear after SMBIOS V2.0. So if you cannot find this string, it means your motherboard doesn’t support SMBIOS v2.0.
Then we go to SMBIOS Structure Table, you should have got the address Addr_ST from the previous step. SMBIOS data stores different types of information in table, one after another. According to the specification, the first table is BIOS Information Table (Type 0), followed by System Information Table (Type 1). The system manufacture information we want to modify is stored in System Information Table, so it’s enough for us to check this table only.
In order to find the start address of System Information Table, we should know the length of BIOS Information Table. At offset 0×0 of BIOS Information Table (Addr_ST), the one byte value is “type”, it should be 0. The length of BIOS Information Table is located at offset 0×1 (Addr_ST+0×1). We directly go to Addr_ST+length, from this address, there are several strings, ends by 0×00. Until we meet another 0×00 after a string end, we can find several strings defined in BIOS Information Table. After 0×00 0×00, the System Information Table comes out (Addr_SIT).
Offset 0×0 of System Information Table, the value 1 stands for the type of this table, just like BIOS Information Table. Offset 0×1 is the length of this table. Go to Addr_SIT+length, we will find several strings defined in System Information Table. These strings are “Manufacturer”, “Product Name”, “Version”, “Serial Number”, “SKU Number” and “Family”. Now we’ve already found the manufacturer string, so just change it from OEM1 to OEM2, our jobs done.
After this hack, I tried to install the application again, and the install shield will no longer detect the platform as OEM1, so the installation finished successfully. Actually, if you check the system information, you can find that the manufacturer is already OEM2.
You may ask how I hack this before OS loading. Well, since I was using windbg to debug the target machine in kernel mode, I can break in the system at a very early point during windows loading. Before windows bootloader (NTLDR or bootmgr) started, BIOS is already mapped into memory and the BIOS POST is finished. After OS taking control of the system, it will read the BIOS information from the mapped address. So if I modify the memory where BIOS mapped before OS reading, OS will get the data which I’ve already changed. In this way, I cheat the OS. This is also the mechanism how the simulation activation of windows vista/windows 7 works: before OS loading, it will change the OEM ID and SLIC table in ACPI table to mislead OS. Then together with an OEM certification and an OEM S/N, windows vista/windows 7 can be “activated”.
If you just want to take a look at the BIOS mapped memory, or you don’t have a kernel mode windbg connection, you can use the following methods.
1. In 32bit windows, or pure dos, there is a very powerful tool “debug.exe”. It can read/write real mode address. For example, if you want to dump the raw data at 0xf0000, you can do in this way:
Run debug.exe
-d f000:0000
Then data located at physical address 0xf0000 shows up.
Be noticed that debug will access the address in [section]:[offset] mode, so you may need to calculate the address yourself. This is the basis of computer architecture.
2. Another powerful utility running on windows platform: R/W Everything. Besides access the physical memory, it has many other functions such as check the PCI bus configuration.
3. Loading GRUB first, then load your customized image, then OS boot loader. This is a very challenging way, also very flexible and powerful. If you can do it yourself, you’ve already started to implement your own OS.
All tools and utilities I mentioned in this article can be found over the Internet.
For the latest SMBIOS specification, you may find it here:
http://www.dmtf.org/standards/smbios
My Flight Sticks
飞行摇杆这个东西,和方向盘一样,只能玩有针对性的游戏,所以用户远不如手柄广泛,而且价格比较高,一直被认为是游戏外设的奢侈品。


第一个摇杆是大四买的,Microsoft Force FeedBack Pro。当时买了个二手货,但质量完全没问题,而且挺便宜的。然后开始玩F-16,MIG-29这些老游戏,当然还有IL-2和Microsoft Flight Simulator.
今年要出IL-2 COD,前一阵又买了个声卡,主板上又么有DA-15接口,又实在不想接两块声卡,于是想想还是再买一个新的杆玩玩吧,于是买了Saitek Cyborg F.L.Y. 5.


总的来说,Cyborg F.L.Y. 5的手感并不如想象中的好。不过买了这么多东西也基本有感觉了,这个价位,对于讲究工艺的产品来说,能有一些优点已经很不错了,要想做到像我买的键盘那种基本无可挑剔,价位总还是要再上去的。
F.L.Y. 5的优点有:便于携带(其实我不需要携带),外型不错,油门的阻尼很舒服,握感还可以。
缺点有:
底盘太轻,不够稳,虽然有防滑垫,但还是不太稳。FFB就好很多。
杆有轻微空抖现象,而且略有零点漂移。
杆的阻尼不够好,启动距离力量过大,远距离力量小。FFB因为有力回馈,所以这种感觉要好很多。
然后想当然觉得,国外应该会有人DIY机械摇杆吧,果然找到一个做的挺好的:
http://www.simprojects.nl/flight_stick.htm
Recent Comments