[News] Freecell
FreeCell & Hearts, Behind the scenes
http://www.codeproject.com/KB/trace/freecellreader.aspx
Introduction
Yep, again. For those of you who liked my first article "Minesweeper, Behind the scenes" I present here his natural sequel. The idea came when a friend of mine read the former article and joked me about it, "now do hearts.." he said, so I did and this article is the final result. At this point I would like to thank some friends who helped me, Itay Langer, Michael Kuperstein and Yoav Sion (in alphabetical order).
Two weeks ago, when I wrote the first article, I've explained the use of API functions with C# (using P/Invoke) to read another process memory. Also I've written an example for using this class library in order to read the Minesweeper mines map. In that article I've claimed and I still claim that the goal of the article was not how to hack Minesweeper. The goal of that article was to provide the reader a simple class library in C# that will allow them to read another process memory. To my surprise, many
people who read the article was very interested in the example I've brought. Because of that I cant really claim that the goal of this article is to learn how to use some new API functions in order to have functionality unsupported by C#. The goal of this article is to see what is happening behind the scenes of the two Microsoft card games: FreeCell and Hearts. In spite of this goal my conscience cannot let me publish an article with no new coding feature, So I've enhanced the library and now it
supports also writing into another process memory. I've even done a use of this function in one of the examples.
Main Goals
1.FreeCell behind the scenes and developing a cool app that uses this knowledge.
2.Hearts behind the scenes and developing a very cool app that uses this knowledge.
3.Write to another process memory using the WriteProcessMemory API function.
Note: The first two sections are using a debugger to investigate the games, my personal favorite debugger is Olly Debugger v1.08 but any debugger will do.
Section 1: FreeCell, How does it work?
I imagine you ask yourself what is to crack in FreeCell? you already see all the cards! Well the point is to understand what it does and how it gets these cards. Also suppose you can read the cards, you can write a program that plays Freecell by herself.. but you must have a way to read the freecell memory.
The first step, like always, is opening the file in the debugger. In this case we need the freecell.exe file which is found in the windows\system32 folder. After opening the file we need to find an interesting starting point. When you look at the beginning of the file you see a list of functions imported from dll's as follows:
01001188 DD USER32.GetDlgItemInt
0100118C DD USER32.SetWindowTextW
01001190 DD USER32.wsprintfW
01001194 DD USER32.GetSysColor
01001198 DD USER32.GetWindowDC
0100119C DD USER32.IsIconic
010011A0 DD 00000000
010011A4 DD msvcrt._except_handler3
010011A8 DD msvcrt._controlfp
010011AC DD msvcrt.__set_app_type
010011B0 DD msvcrt.__p__fmode
010011B4 DD msvcrt.__p__commode
010011B8 DD OFFSET msvcrt._adjust_fdiv
010011BC DD msvcrt.__setusermatherr
010011C0 DD msvcrt._initterm
010011C4 DD msvcrt.__getmainargs
010011C8 DD OFFSET msvcrt._acmdln
010011CC DD msvcrt.exit
010011D0 DD msvcrt._cexit
010011D4 DD msvcrt._XcptFilter
010011D8 DD msvcrt._exit
010011DC DD msvcrt._c_exit
010011E0 DD msvcrt.isdigit
010011E4 DD msvcrt.time
010011E8 DD msvcrt.srand
010011EC DD msvcrt.rand
This is only the final part of the list, but If you look carefully you see that the last imported function listed is the function rand from the msvcrt dll, which is off course the randomize function from the microsoft visual c runtime dll. So I've decided to search where this function is being used.
I've found two places where this function is being used. Then I put a breakpoint on both places and run the program. After I've started a new game the program stopped on the first breakpoint once and 52 times on the second breakpoint. Here is the part where the brain needs to kick in, mine said that the first breakpoint randomize the game number and the second breakpoint randomize the position of each card (or the card of each position) (remember you got 52 cards..).
So, I did a little test to prove me theory. I ran the program till the first breakpoint, then step over the rand function and look at the eax register, the value of this register was 0x00006A26, then I continue to run the program, the game number (displayed in the caption) was 25254.. bingo, 0x6A26 = 25254. So now I knew I was right I needed to find where freecell stores this value and the cards values, so I could read them later with my program. I started a new game and now I've investigated the second
breakpoint. A few instructions before the breakpoint I've found a very interesting piss of code. The code I've found store a value in a specific place in the memory, and then formatted the string "FreeCell Game #%d" with this same number, so THIS is where it stores the game number.. The code is presented here:
010031D0 MOV DWORD PTR DS:[100834C],EAX
010031D5 PUSH ESI
010031D6 PUSH EDI
010031D7 PUSH 80 ; /Count = 80 (128.)
010031DC MOV ESI,freecell.01007880 ; |
010031E1 PUSH ESI ; |Buffer => freecell.01007880
010031E2 PUSH 12F ; |RsrcID = STRING "FreeCell Game #%d"
010031E7 PUSH DWORD PTR DS:[1007860] ; |hInst = 01000000
010031ED CALL DWORD PTR DS:[<&USER32.LoadStringW>>; \LoadStringW
010031F3 PUSH DWORD PTR DS:[100834C]
010031F9 PUSH ESI ; |Format => ""
010031FA MOV ESI,freecell.01007820 ; |UNICODE "Cards Left: %u"
010031FF PUSH ESI ; |s => freecell.01007820
01003200 CALL DWORD PTR DS:[<&USER32.wsprintfW>] ; \wsprintfW
01003206 ADD ESP,0C
01003209 PUSH ESI ; /Text
0100320A PUSH DWORD PTR SS:[EBP+78] ; |hWnd
0100320D CALL DWORD PTR DS:[<&USER32.SetWindowTex>; \SetWindowTextW
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.44.147.81
→
12/02 18:09, , 1F
12/02 18:09, 1F
噓
12/13 16:25, , 2F
12/13 16:25, 2F
EngTalk 近期熱門文章
PTT職涯區 即時熱門文章
19
61