How to force non-windowed games into Windowed mode

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
I have been using - pretty successfully - [DxWnd] so far, to get the job done. Recently, I had to move to Win10 (unfortunately), and currently [DxWnd] no longer gets the job done for AC Black Flag (and probably other games as well). I'm sure I'll get it running eventually...

In the mean time, a quick google brought me here: 'How to run Assassin's Creed IV: Black Flag in Windowed Mode youtube'. [Nirsoft's WinExp](lorer) also seems do this job well (be it far less limited in options)...

ps: I recall #Sunbeam posting an article on the subject for AC 4 specifically; but couldn't find the post anymore. #mgr.inz.Player made/posted a small hack (based on that article) @CE, but his hack_tool did not work for me either...

ps2: if you know of other similar tools, feel free to post them here. Preferably verify that these do work on Win 10 (per definition now the "standard" OS... ahum by choice)

-EDIT-
An important detail I forgot to mention: you must first change/decrease your game's resolution in respect to your current/max window resolution (or "nothing seems to happen")
 

fantomas

Expert Cheater
Table Maker
Joined
Mar 25, 2017
Messages
1,287
Reaction score
548
Paul44 said:
ps: I recall #Sunbeam posting an article on the subject for AC 4 specifically; but couldn't find the post anymore.
https://fearlessrevolution.com/viewtopic.php?t=686
 

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,483
Reaction score
1,866
Generally speaking, you'll have to learn a bit more WinAPI to understand the whole concept behind windowed mode. First-up, as with any software, you want to catch where the software creates its main window. Games too are software, so there will be a call to CreateWindowExA/W before you even get to see the main window. After it's created, it's initialized and then using ShowWindow you get to actually see the frame of it. Past this, you want to intercept the DX init call. In most games using d3d9.dll, Direct3D is invoked via the Direct3DCreate9() API. The return value is a pointer to a Direct3D interface, IDirect3D9. From that you want to get to CreateDevice() API and fiddle with the D3DPRESENT_PARAMETERS. That structure contains the bWindowed BOOL that can be set from 0x0 to 0x1 to start in windowed mode. You can do this via x64dbg or CE, for that matter, without DxWnd.

Here's a quick PDF to get you through it all: https://download846.mediafire.com/n5zif4hgypug/16enttgsycb97we/Silver-DirectX-Solution-TheColonial.pdf

If I remember correctly, I used it in figuring out the Black Flag windowed mode (and all other old ACs'). The same applies to any DX10, DX11 or DX12 games that don't feature a "windowed" option (either setting in-game -OR- Alt+Enter or whatnot).

BR,
Sun

P.S.: Think I have the CrackeMe as well; here's the link: http://www.woodmann.com/forum/showthread.php?9600-DirectX-crackme. CrackMe itself is on page 2 here.
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
Direct3D intercept...

Just to be clear gents, I only needed it to allow me to debug AC 4 (or similar games); not because I wanted to know how to hack such feature. In the mean time, I've placed a request @DxWnd: time permitting, some suggestion/update might come along...

@fantomas: while it is for Rogue, it is (probably) helpful. (sorry, can not really spare the time atm to figure this all out)
@Sunbeam: I should NOT ask this question (since I really can not follow this up), but logically that would/could mean that this call can also me made from - let's say - the main game menu (rather then hacking the exe directly)? Again: it's an open Q, and this kind of stuff honestly does not lay within my 'boundaries of interest' :oops:
ps: did download pdf/crackme, and will give it a go one of these weekends... (and thx for feedback ofc)
 

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,483
Reaction score
1,866
^ Regardless of the game, the method is UNIVERSAL. That's how DX games are conceived, that's the loading logic and order. That's how you should debug the game and that's how you should find the D3DPRESENT_PARAMETERS structure. Once found, it's a matter of taste how you patch the executable. And no, you can't do it AFTER the game has loaded, as changing the flag won't reset the device. It always has to be done between creation of game's window (CreateWindowExA/W) and ShowWindow. Why.. because the D3D initialization happens in-between. By the time ShowWindow API is called (you can easily get what this does), the D3D device should already be initialized and mode already established (full-screen, windowed, etc.).
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
I had this on my todo list, and did some experimenting with it... on AC BF. Tried the AC3 walkthrough (see below), which partly helped.
Bottomline: at some point, simply tried to update that mem_location manually... and this worked fine (?!) using CE

Script:
*********************************************************
[ENABLE]
{$lua}
local bytes = "F7 DE 1B F6 33 C0"
local memScanner = createMemScan()
memScanner.setOnlyOneResult(true)
memScanner.firstScan(
soExactValue,vtByteArray,rtRounded,bytes,nil,
0,0xFFFFFFFF,flag,fsmNotAligned,"",true,false,false,false)
memScanner.waitTillDone()
addrD3D = memScanner.getOnlyResult()-0x7+0x3
local bWindowed = readInteger(addrD3D)
-- 0 = windowed ~ 1 = fullscreen
writeBytes(readInteger(addrD3D),0)
memScanner.destroy()

--print(string.format("%x",bWindowed))

[DISABLE]
{$lua}
writeBytes(readInteger(addrD3D),1)
*********************************************************

Some observations:
a) the fact that this 'window' sticks in the left_top corner, is probably because the 'window_rectangle' is still set to "fullscreen". Iow if one could also pass on/update 'win_settings', one could probably get a "manageable" window
(GetSystemMetrics and/or AdjustWindowRect ?)
b) I was kinda hoping that this "trick" would also apply to AC 3 (and other x32 games): unfortunately, it does not... exact same code, but the game seems to hang/halted when changing the value to 0; setting it back to 1 gets it "unlocked" again...
c) also tried this with AC 1 Deluxe; code completely different. seems to be more similar to x64 code (had a look at AC Unity before that)


ps: I also came across #Sunbeam's doc about how to do this with AC 3. Unfortunately, to proceed one has to add a 'EB FE' (~ apparently a shortjump on itself) at the entry point (EP); an instruction I could not perform since no idea where/how to locate that EP...

ps2: I have added this option to my AC4 table, but will not yet upload it (unless requested)

ps3: all these games can easily be windowed with 'WinExpl'; no problems there (as long as you choose smaller res)

ps4: did research using [x32Dbg~x64Dbg]
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
^continued...

Found something interesting while testing FreeRoam coordindates: see here [ https://imgur.com/a/u9fkogI ]
Basically: one can play AC4 in "true" window (instead of it pinned in the upper_left corner). And yes, window can be dragged across the desktop!

One of the EXEs I have (and use to test), is slightly different compared with the others and gave me a true window. After some research, I found this:
*****************************************
"AC4BFSP.exe"+5C1EC: F3 0F 11 86 50 01 00 00 - movss [esi+00000150],xmm0
"AC4BFSP.exe"+5C1F4: 66 89 86 48 01 00 00 - mov [esi+00000148],ax
"AC4BFSP.exe"+5C1FB: 88 8E 82 03 00 00 - mov [esi+00000382],cl
// ---------- INJECTING HERE ----------
"AC4BFSP.exe"+5C201: 88 86 13 1B 00 00 - mov [esi+00001B13],al
// ---------- DONE INJECTING ----------
"AC4BFSP.exe"+5C207: C7 86 4C 01 00 00 02 00 00 00 - mov [esi+0000014C],00000002
"AC4BFSP.exe"+5C211: 89 8E 54 01 00 00 - mov [esi+00000154],ecx
"AC4BFSP.exe"+5C217: 88 86 3F 01 00 00 - mov [esi+0000013F],al
*****************************************

All my EXEs - except this one - have this opcode: mov [esi+00001B13],cl
(just to verify, I patched the latest vs accordingly, and indeed I had it running in a true window)

It would be interesting to find out which struct [esi] represents; and changing that value to '0'...? (while in main menu)

To be continued...

-UPDATE-
a) In the mean time, I found out that [esi] references to the same record table as mentioned in my prev post. In fact, the val mentioned here - [esi+00001B13] - is the very same value...
b) I also worked out a batchfile to easily patch the game's exe (see AC BF topic). As a point of case, tried out above "feature" with AC 3, with the same/windowing result (will post that some time later this week)... Unfortunately, the Window Mode flag still does not work as it does with AC 4?!

-UPDATE2-
after recomparing with #Sunbeam's doc, it corresponds with his findings. Funny thing: the exe in question has a timestamp of 8th Feb 2020; and I have no idea how I got that exe in the first place... a troll maybe?
 

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,483
Reaction score
1,866
Note you can't really compare AC1 with Unity :) AC1 is x86, as far as I know. Unity is x64 :p You're saying you tried to compare apples with pears :D
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
^ok, "comparing" is a too strong word here; actually meant to say: "looking for similarities" (and 'we' also use the same expression in my country as well; 'apple vs pears' I mean ;) )

But one thing is definitely "similar" between all EXEs (32/64b): the "location & manner" where/how that flag is set. Meaning: you will find similar codes such as this one:
"AC4BFSP.exe"+5C1EC: F3 0F 11 86 50 01 00 00 - movss [esi+00000150],xmm0
"AC4BFSP.exe"+5C1F4: 66 89 86 48 01 00 00 - mov [esi+00000148],ax
"AC4BFSP.exe"+5C1FB: 88 8E 82 03 00 00 - mov [esi+00000382],cl
"AC4BFSP.exe"+5C201: 88 86 13 1B 00 00 - mov [esi+00001B13],al
...

While I'm not so much interested in getting these games windowed per se, I was/am definitely interested in practicizing the technique you used here... So, by now, I understand how to get to the EP (not so difficult apparently, once you get your preferences right ~ and having Scylla installed sure helps as well :| )

So, my status on the subject here:
a) I can now figure out (and follow them instructions) for AC 3/4/5; no probs there.
b) obviously wanted to try this out on AC 1 & AC 2 as well (will do BR & RV later on):
* AC2: could not find the/a 'flag' in proximity of 'CreateWindow', but backtracking allowed me to find that location eventually
(if I recall well, followed the 'AdjustWindowRect' function ~ at some point the window gets created,; followed the call that did that...etc ~ if someone is interested, pm me and I'll get you some ptrscreens)
Array of bytes:
set "origHex=888E73200000"
set "replHex=888673200000"
...
The game launches/runs fine... until I swap out and back... the game continues running, but window turns black/does not get updated... (runs fine when using DxWin 2.05 btw)
* AC1~DX9 (DX10 allows windowing "by nature"): also backtracked this, but no effect/result sofar. I do think I got the correct opcode, but changing the flag does not give me a windowed vs.
That said: using DxWin 2.05 does give you a nice window as well (btw: latest release - far more elaborated - also launches in window, but game crashes before reaching menu...?)


@Sunbeam: I do have one (well...) question though (now that I've spent some time on this): how did you figure out that it is/was actually that particular flag, setting the 'window vs fullscreen' boolean? Magic... ?
I did some (limited) reading on the 'CreateWindow' function; compared with the values shown on the stack (seem to be fine/correct/corresponding with that fn's parameter list)... Unfortunately: nothing in the MS doc that tells you how to distinct the 2 modes; basically what to look for... One sees distinctively 2 values for 'styles': '80000000' vs '00CA0000'; but it is not clear to me that these values "do the trick". (and yes, I did try... :cool: )

Anyways: now that I see how "easy" it is (can be) to get 'windowed', I can not (yet) understand why developers do not implement this as a basic feature. I never play games windowed (except for FreeCell & Mahjong :D); so no experience on possible crashing with games set this way along the playroute...


FYI: I started with xdbg a real long time ago, and back then I could not place most of it. Now that I'm starting to see the picture "less blurry", I can't but say that I'm really impressed with this debugger. The 'Restart' function in particular, I like very much; especially for cases such as this one !
And no - for anyone interested - you can not compare this debugger with CE; it's like... what's the expression again? hummm...
 

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,483
Reaction score
1,866
Paul44 said:
Meaning: you will find similar codes such as this one:
Ubisoft moved from x86 to x64 between Black Flag and Unity. Unity uses the same Engine, 64-bit version, as Black Flag did. So of course there will be similarities. It's like porting same code from x86 to x64 :)
Paul44 said:
I understand how to get to the EP
Getting to EP is just a simple F9. However.. the reason I used that EBFE (infinite loop) method was the fact that when you run the game.. the .exe starts uplay launcher and dies. The launcher then runs the .exe again, and then the actual game runs (after logging you in, per se). So.. EBFE at EP allows you to attach debugger to .exe, then break on that EB FE, restore bytes at EP so .exe runs. Then the .exe runs UPlay launcher like normal.. and when UPlay launcher runs the .exe, the .exe will be stuck in the infinite loop ;) Then you can attach debugger again to the process, restore EP bytes and continue execution, debugging from start of process till that location where you patch stuff up. I used the original executable here, not some cracked version. In the original, you have to pass through UPlay launcher.. so yeah..

Regarding AC2, please check the parameters with which that CreateWindowExA is created. MSDN will help you read more on it. Make sure the flags are identical to those WinExp shows.
Paul44 said:
how did you figure out that it is/was actually that particular flag, setting the 'window vs fullscreen' boolean? Magic... ?
I did link a tutorial in a PDF document, didn't I? Did you read it? That's how -> https://fearlessrevolution.com/viewtopic.php?p=125678#p125678.
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
^ yep, got that doc/sw downloaded; and placed it in my Todo Folder (after a short glimpse on the first 2 pages, I said to myself: "F(peep), not today tyvm" :)
Since I had no plans to dive into this at that time, completely forgot about it (sorry about that). But like many countries, mine is in 'lockdown' since April; so partially "unemployed" at the moment. And thus sharing my "new" freedom between this stuff, house renovation and GF (preferably in that order :))

fyi: tested AC BR & AC RV last night: they use the same flag "location" (/opcode) as AC 2. With 1 minor difference: these 2 games do run nicely windowed (not turning black upon tabbing). There is flickering with AC RV, but DxWin also shows the same flickering...
 

MartaLabieniec

Expert Cheater
Joined
Oct 6, 2018
Messages
279
Reaction score
118
SunBeam said:
^ Regardless of the game, the method is UNIVERSAL. That's how DX games are conceived, that's the loading logic and order. That's how you should debug the game and that's how you should find the D3DPRESENT_PARAMETERS structure. Once found, it's a matter of taste how you patch the executable. And no, you can't do it AFTER the game has loaded, as changing the flag won't reset the device. It always has to be done between creation of game's window (CreateWindowExA/W) and ShowWindow. Why.. because the D3D initialization happens in-between. By the time ShowWindow API is called (you can easily get what this does), the D3D device should already be initialized and mode already established (full-screen, windowed, etc.).
Is this method working also for Direct3D, Software, nGlide, 3dfx Voodoo and DOS renderer? Or only for DX renderer?
 

kantoboy69

Expert Cheater
Table Maker
Joined
Aug 30, 2019
Messages
89
Reaction score
41
Windows 10 feature task view, add virtual desktop
put the game in main desktop
then cheat engine in the virtual desktop

ctrl + windows key plus left/right arrow to change desktop

It's another alternative
 

Paul44

Expert Cheater
Table Maker
Joined
Jul 27, 2017
Messages
149
Reaction score
43
^ I was not aware of that feature. Just tested it, and indeed workable. Not as flexible as with a Windowed game, but definitely another good option to work with. thx for that.


On another note:
I got most AC (non-windowed) titles working as per above instructions. However, AC BR & RV can not be moved around (because of missing system_menu); and surely this is because of its 'dwExStyle' settings. Did some reading (and verified those titles that do work), and concluded that these 2 titles do not seem to set any "style". The others seem overall to use '0x00CF0000' (see also below)

So I figured, I could "insert" some code right before the 'createWindow'. Never done this before, so took some trials (10+) to actually get the stack values correct... or so I though. No cigar, meaning I need some suggestions here now...

{ (using x32dbg)
00E544E0 | 83 EC 14 | sub esp,14 |
00E544E3 | 90 | nop |
00E544E4 | 90 | nop |
00E544E5 | 90 | nop |
00E544E6 | 90 | nop |
00E544E7 | 90 | nop |
00E544E8 | E8 23 D0 FF FF | call acrsp_wind.00E51506 |

("inserted" right before CreateWindow ~ problem here is that they push edi (=0) to the stack...)

(using some 'CC chunk' to insert cave code here)
00E51504 | CC | int3 |
00E51505 | CC | int3 |
00E51506 | C7 44 24 14 00 00 CF 00 | mov dword ptr ss:[esp+14],CF0000 |
00E5150E | C7 44 24 10 00 00 00 00 | mov dword ptr ss:[esp+10],0 |
00E51516 | C7 44 24 0C 00 00 00 00 | mov dword ptr ss:[esp+C],0 |
00E5151E | C7 44 24 08 00 05 00 00 | mov dword ptr ss:[esp+8],500 |
00E51526 | C7 44 24 04 D0 02 00 00 | mov dword ptr ss:[esp+4],2D0 |
00E5152E | C3 | ret |
00E5152F | CC | int3 |

}

Before I go diving into 'D3DPRESENT_PARAMETERS' (and how to find that struct), I would be interested to know if above is actually doable?!


****
Took me some more googling to wind up here: [ https://chentiangemalc.wordpress.com/2014/05/28/case-of-the-full-screen-app-hidden-by-the-taskbar/ ] (I have not yet tried out the tool mentioned in that article): basically, one would like to get this style:
{ (andnow I also now that these values are 'totaled')
WS_OVERLAPPEDWINDOW is actually several styles rolled into one:

WS_OVERLAPPED (0x00000000)
WS_CAPTION (0x00C00000)
WS_SYSMENU (0x00080000)
WS_THICKFRAME (0x00040000)
WS_MINIMIZEBOX (0x00020000)
WS_MAXIMIZEBOX (0x00010000)

Adding it all up we get:

0x00CF0000

}
 
Top