Jump to content
Search In
  • More options...
Find results that contain...
Find results in...


  • Content count

  • Joined

  • Last visited


About xttl

  • Rank
    Junior Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. xttl

    EXE hacking

    Relative call/jmp works with addresses up to +/- 2GB, so regular function calls are not a problem at all. Function pointers need to use absolute addressing though, as do all references to the data section. The sources posted on the previous page should explain everything pretty well, but here's a summary: exe is prepatched with some new code (138 bytes, asm source is on previous page) and a call to there on startup, the call replaces part of the press beta's date&password check code and the rest i just skip over, so no need for fakedate.com and those batch files anymore. this code overwrites an unused function in the beta exe (D_TimingLoop which does a thing that's very similar to the timerefresh console command in quake if you know it, rotates the view 360 degrees once and then drops to dos with some timing info displayed) i modified the LE fixup table to remove* any fixup records (3 total) which would otherwise cause dos4gw to overwrite parts of this code, because D_TimingLoop references some global vars and a string from the data section prepatched new code uses open/read/close/filelength/malloc code already present in the original exe, no problems here because the relative call instruction works with addresses up to +/- 2GB like mentioned previously. loads a file called "stage2.bin" from the same directory on disk to a malloced buffer, and does an absolute call to the buffer's address call $-5 calls the next instruction right after it (wherever it happens to be in memory), so if you write pop <register> after the call you can get the current EIP value in that register no matter where the code is currently located in memory, no need to peek into the stack deeper than that (nothing I posted on previous page peeks into the stack to get pointers) then you can subtract from that value the address which the pop instruction following the call would have been at if it weren't relocated, and now you have the code section relocation offset, you can use this knowledge to address anything located in the code section read a known data pointer value from somewhere in the code section, subtract from it the expected unrelocated memory address of that data, and now you also know the data section's relocation offset you know what address malloc just gave you for the buffer you loaded stage2.into, that's the base address for all code and data loaded from that external file. then just put or keep these values in the registers before directing execution flow into the buffer (btw. I originally chose ESI = cs offset, EDI = ds offset, EDX = stage 2 base, but changed these after I started experimenting with compiled code because EAX, EDX and EBX are the register watcom's calling convention uses) "Can all game code be directly referenced as an offset of EDX?" <- yes, just add the address you see in IDA or some other disassembler or listing which shows addresses the same way. For example, if the first byte of the code section was at 0x10000 (it's preferred load address), then exit and printf from libc would be at: cseg01:000436CE exit_ cseg01:00042D40 printf_ If the first byte of the data section was at 0x50000 (preferred), then this sound debug string from the original game code would be at: dseg02:000583EC aSomethingSFuck db 'Something',27h,'s fucked. Distance to sound < 0.',0 So you could write a stage2.bin which uses printf from the game's libc to print that string from the game, a string from stage2.bin itself and then the libc exit function like this: BITS 32 org 0 lea ecx, [edx + 0x42d40] ; printf lea esi, [eax + text] ; text from this binary push esi ; string pointer for printf call ecx ; add esp, 4 ; lea esi, [ebx + 0x583ec] ; "Something's fucked. Distance to sound < 0." push esi ; call ecx ; still points to printf add esp, 4 ; lea ecx, [edx + 0x436ce] ; exit mov eax, -1 ; program exit code jmp ecx ; never retuns text: db "hello from stage2",0x0a,0 (why exit? well I_Quit / I_Error try to do some deinitialization IIRC which is not a good idea at this point in startup) Relocation is done per-section, (not per-page or anything crazy like that luckily, that wouldn't work very well with code anyway because it's better to use relative jumps/calls whenever possible of course you can always rewrite relative pointers too, I was already doing that to patch in calls in the loader when I wrote that but I still keep forgetting it... see, this is why I don't do this as a job :D) so because there are only 2 relevant sections in the executable you really just need 2 offsets to address everything. * really I just made them all clones of another fixup record which fix up addresses nearby, I didn't want to use the tool I made which always regenerates the whole fixup table because that would cause a huge bindiff while manually hex edited this way it's only a 9 byte difference to the original file I am too tired right now, but I'll write more tomorrow. I almost just got replacing a function in the game with compiled C code from the loader working, but there's some strange problems with it and I can't figure out why it's not working at least until I sleep.
  2. xttl

    EXE hacking

    The call/pop trick was actually originally mentioned by budko (the prboom+ coder, also the doom+ series creator) on #doom-tech or somewhere else on IRC I was lurking years ago, though I think at some point the realization would have dawned upon me regardless*, and you could alternatively also modify the fixup table to make the program loader write the relocated addresses of the start of CS and DS somewhere your code can grab them. (granted this isn't as easy as it could be because the LE format seems to be overall really shitty and stupidly complex, just look at it and compare to eg. PE which has also always had relocation support for DLLs and nowadays ASLR enabled executables, but at least I managed to write that tool earlier to help a bit with this) *(even if I'm not a particulary expert or experienced programmer or even good or a professional in this field, really I just hack on old games as a hobby sometimes, maybe a bit like some people do puzzles and riddles stuff like that) When you know where the code and data sections of the game binary are in memory at runtime, it's already easy to start doing small changes with some memory reads and writes. You can try this yourself with that newdhack.exe file I just posted inside that zip, just use NASM or something to assemble a stage2.bin which does some movs. When the code in stage2.bin starts, EDX contains the relocation offset for game code and EBX contains it for game data, and in EAX you have the address where the code in stage2.bin was loaded. At the end of the file you just put a RET to go back to the 1st stage loader (which is in the EXE, I overwrite an unused function with it and then overwrote part of the date + password check code on early startup with a call to there). You don't really even need to save/restore any registers yourself because the loader I patched into the game exe does pusha/popa already and the call to stage2.bin is the last instruction before the popa and ret back to original game code. So for example, if you wanted to change plat speed to match the release version (0x40000 vs. 0x10000) you could write this: BITS 32 org 0 mov [edx + 0x2eb60], byte 0x04 ret and assemble it with NASM (raw output) to a file you name stage2.bin and put in the same directory with newdhack.exe before you run it in DOSBox. If you look at newdoom.exe in any disassembler that shows you addresses as they would appear in memory without relocation*, you see that this overwrites a byte from the immediate value included in this instruction inside EV_DoPlat: cseg01:0002EB5B mov dword ptr [eax+10h], 10000h *(note that the preferred load address without relocation specified in the LE headers for the code section is 0x10000 and not 0, and for the data section it's 0x50000, this is why I already renamed the vars in the C code I posted on last page to csrelo/dsrelo from csbase/dsbase because what stage1 loader really gives you is the relocation offsets = difference vs preferred address, not relocated start of the section, that would be the difference+0x10000 for code or difference+0x50000 for data) That's not a change that would be hindered by DOS4GW rewriting all non-relative address references on startup though, because it's just an immediate value inside an instruction (and the memory write it does is to an address relative to a register but even if it wasn't the relocation record would still hit just the address part of the instruction here) so let's try something else next: BITS 32 org 0 lea ecx, [edx + 0x248d4] mov [ebx + 0x5221c], dword ecx ret This changes a function pointer inside the menu definitions in data section so that the first selection in the main menu ("Demo Map 1") now activates the previously disabled but hidden in the code options menu. This is something you'd normally need to know to change in the relocation table instead because the function pointer inside the menu defs needs to be rewritten obviously when the game's relocated in memory (it's not a relative reference like jmps/calls back and forth inside the code section). For anybody not even superficially familiar with x86 assembly: note that the lea instruction does not do any real memory access despite the square brackets, it's just used for calculations (it's intended for memory address calculations but can be used for any calculations really, and sometimes it's more optimal to calculations that way, though here you could just do add edx 0x248d4 and use edx as the source in the next instruction if you didn't care about losing the value in edx which is the CS relocation offset). (beware the screen size control in the options menu btw., you can play around it with but if you expand the game view to fullscreen then something bad happens when you quit the game, it's probably overwriting something in memory just before the screen buffer because the view is drawn a bit too high with a few pixels of the status bar still showing in the bottom, I needed to go to a virtual console with ctrl+alt+f2 to kill dosbox because after quitting the game it went into a state where it made X totally unresponsive. maybe it doesn't break on Windows like that but I don't really use Windows anymore because Win10 is such a disaster, so it's difficult for me to say anything for sure about that) None of this really helps with making more significant changes to the game code any less tedious work (where you have to keep track of the byte position of all memory address references in your code all the time) though, unless you can somehow automate the process of always applying address fixups to the correct locations in the replacement code. Because the LE format is annoying to work with I think it's easier to accomplish this via a runtime loader approach than something which would generate fixup records for LE headers automatically. Now I'm really not some secret closet master wizard programmer, as unfortunate as that is (I've completed the first page of puzzles in TIS-100 once but that's it, and even those were often very unoptimal and sometimes silly solutions though they worked), so I gave up on programming a rebasing loader for code chunks of any kind (even for a real simple format I'd "design" myself on the fly) in assembly almost right away and started looking at the possibility to use C for this. Using compiled code for patching Watcom-made game binaries is something I had really wanted to make work earlier already but I gave up on it because I had only been looking at compiler and not linker output, and that format looked just disgusting. Well, now I finally looked at the linker output instead and in the end it turned out it isn't difficult at all to make this work at least on the level seen in the previous post. It's really fortunate that Open Watcom can make PE DLLs if you select the win95 or nt target, it's such a nice and easy format to parse compared to OMF32 or LE/LX, and then I just had to figure out ways to work around the fact that I don't have any kind of runtime dynamic rebasing loader yet in the C code. I cannot really replace ingame functions from compiled code yet though, because how would I pass the pointers to the vars/funcs structs to some code that isn't called from the start function without resorting to doing something silly, like storing them to some fixed address in low DOS memory, video memory or elsewhere where I could maybe get away with it, for later access? edit: well, a fews mins after posting this I realized that I could of course go into the stack in my new function when it's called by the game get some pointers to known locations, and proceed from there... lol, maybe I'll go code that next What I have already is enough for writing a rebasing loader much easier than using pure asm though, maybe for the simple format first and DLLs later, or maybe I'll just attempt DLLs right away.
  3. xttl

    EXE hacking

    Hello, I haven't been active here for a while, and I don't have anything big to release right now but I'm too happy to not bump this thread since I just finally got EXE patching using compiled C code working (after about two-three days on and off looking at and trying out things). There are limitations and the way I have to write the code is a bit strange and unwieldy, like this: (that's a quick test I wrote right after I got this thing working for the press beta exe which patches movement keys based on a 4-byte keys.cfg file, makes the doomguy always run and changes plat movement speed to match release version) Now the only thing I have to write in assembly and patch directly into the exe (while dealing with LE relocation crap getting in the way all the time) is a very simple and short loader, which just calls the open/read/close/malloc funcs originally linked into the binary to load a flat bin file from the disk into a memory buffer which contains some code that it can do a call into. A suitable stage2.bin file can currently be generated by using Open Watcom to compile and link a Win32/NT DLL file (with specific settings and limitations) and then running a hacky and kludgy tool I wrote in a few hours on it, which I am not going to release at least for the time being. (PE is probably the nicest and friendliest to work with of the formats the OW toolchain can generate out of the box, relatively easy to parse and with good tools and specs available from the net. LEs suck, and last time I was working on this some years ago I made the mistake to only consider using the OMF32 object files the compiler makes for this instead of looking at linker output... they're so massively annoying and complex to parse I just gave up on the idea completely. And right now I can't seem to even find a spec on the web anymore which includes all of the OMF record types wcc386 generates, last time I think I did eventually find one...) Btw. the binary is called stage2.bin because I am going to try at some point to use what I got so far to write a loader for real PE DLL or maybe even ELF files. So it's a "second stage loader". Is it possible to post hidden (must click to expand) code snippets here? I would have never bothered if this was going to be used just for some silly hacks for a game that's been open source for about 20 years now, but now I might even finish some of the hack projects (especially the Doom press beta hack) I started since it's going to be a lot less tedious work for me, at least if I can develop this thing further to the point where I can just compile and drop in replacements for whole fucntions from the original game code. I've attached newdoom.exe with my stage1 loader patched in + a stage2.bin compiled from the above code if somebody wants to play the beta with good plat speed, keys, autorun and no date/password check. :P Oh yeah, I've only tested it in DOSBox, I'm interested to hear if it works on real hardware too (but I see no reason why it wouldn't). edit: forgot keys.cfg from attachment pressbeta_hack.zip
  4. xttl

    Chocolate Doom

    Yes, that works (except that it breaks the ingame music volume control but I can live with this). Thanks for the tip. edit: Seems to also sometimes leave stuck notes when changing songs. I worked around this by adding a short mid file containing a GM reset message to the aplaymidi command line. That causes a bit too much of a delay when looping songs, but I'll also work around this later by hacking the code a bit (I'll have to make it use the reset file only when actually changing songs, not when looping).
  5. xttl

    Chocolate Doom

    Is it possible at all to make Chocolate Doom output MIDI to an ALSA MIDI port on Linux somehow? Currently I can use this port to send MIDI messages to VSTi softsynths running under savihost in Wine (Yamaha S-YXG50 and Roland SC-VA) from DOSBox: $ aplaymidi -l Port Client name Port name 14:0 Midi Through Midi Through Port-0 but I can't figure out a way to do this in the version of Chocolate Doom I just got from the git repo and compiled. From what I see I guess SDL2_mixer simply doesn't support ALSA MIDI at all? If so, that's really unfortunate because that would also prevent using old hardware Roland MIDI modules with Chocolate Doom on Linux. Especially since it's possible to make this work in Chocolate Doom on Windows, even the newest versions.
  6. It isn't really much of a pain to get Quake's IPX or serial multiplayer working in DOSBox, though. :P And on the other hand, TCP/IP is not even possible to enable with just editing the config file or entering commands. Really, plain old WinQuake and some of the NetQuake ports are much more annoying to get to work in multiplayer mode than DOS Quake's IPX networking in DOSBox. They need ports open or forwarded on all client computers and not just the server, and they also select random port numbers for this. If even one of the players has a connection with ISP controlled NAT or firewalling they can't configure you have to resort to using VPNs. QuakeWorld and ports based on QW code are much better about this but unfortunately QW does not support coop mode and not all people like the changes that were made to optimize bandwidth usage for dialup.
  7. That option only works if you start it from under Windows 95 using Q95.BAT (or: qlaunch quakeudp.dll quake.exe -mpath). In pure DOS you'd need to have the Beame & Whiteside TCP/IP stack loaded. QuakeSpasm looks ok to me even though it's GL only, just disable all texture filtering from console. It has proper support for overbrights in lightmaps and fullbright colors in the palette unlike original GLQuake and some OpenGL-based ports. The only thing missing is the original underwater screen effect. VKQuake (Vulkan-based) has it but obviously requires a Vulkan capable graphics card and last time I tried it had some annoyances compared to QuakeSpasm (weapon viewmodel is always drawn too low, no way to fix it I could find). I really prefer QuakeSpasm with colored lightmaps + liquid surface transparency to plain software Quake nowadays even though for a long time I didn't like GLQuake at all because of the missing overbright support.
  8. You don't really need any gear for S-YXG50 though because it's a software synthesizer. :P (one that sounds very much like old mid-1990s Yamaha hardware GM+XG synth modules such as a MU80 which I owned for a while) It's old but there's a hacked VSTi version which is easy to find and (unlike the original driver version) runs just fine using savihost on any modern Windows version. You can also make it work with any MIDI player software, DOSBox, old game, source port, whatever by installing loopMIDI and CoolSoft MIDIMapper. It can even be made to work on Linux-based OSes (probably everywhere else too where wine is available so you can run savihost+VSTis and there's some way to do MIDI loopback). I use a setup like this when I play old games nowadays whenever I'm not using Roland's SC-VA VSTi instead.
  9. xttl

    PrBoom RetroArch port on VITA

    Last time I tried it prboom via RetroArch wasn't very good but this was in the early days of Vita homebrew, the original Henkaku exploit for OS v3.60 had only been released a few months prior. No analog control is a deal breaker. Maybe it has been improved since then or maybe I just couldn't configure it properly :P Honestly I've never really liked RetroArch much (no offense to devs intended, I can appreciate what they're trying to do) but I use it when there's no other working emulator. To answer the questions (if someone else besides the OP is still interested in this): 1. If you get a Vita or PSTV on System Software 3.60 or lower it isn't very difficult at all. You just use the Vita's web browser app and go to henkaku.xyz, your Vita gets exploited and if you don't have it already the website also installs molecularShell automatically (it's a file manager which you can use to install additional software from VPK packages). Up to 3.68 is exploitable using h-encore but I'm not sure how the process goes there because I bought my Vita back in the 3.60 days and haven't updated it. From a quick glance it seems it isn't really more complex, slow or costly (=it's free) to use even though it's a gamesave exploit and not a browser exploit. If you want a persistent exploit that's always applied at early boot time you need to install Henkaku Enso which is only available for up to OS 3.65. I'm not sure how the situation is currently on PSN/SEN access, back in the day it took a long while before Sony eventually blocked access on 3.60. You may also run into a situation where you can use SEN to play multiplayer games but you cannot buy anything from the store anymore. There are ways to get DLC on the Vita even if you cannot access the store directly from the console and you can always backup/restore everything you've bought already. Games which require a later OS version than you have installed don't work unless you somehow get a decrypted dump from another console on later OS and even then not always, but official releases for the Vita dried up years ago so it shouldn't really matter. (I use mine mostly for the excellent PSP compatibility mode and homebrew emulators, there are even unofficial patches for some PSP games that add support for the second analog stick on Vita which is great... well at least used to use, I haven't really touched it in many many months now... ) 2. Nowadays on a hacked Vita you can use microSD cards instead of those expensive custom Sony memory cards with an extremely simple and cheap passive adapter (don't pay more than about 1-5 dollars or euros for this, maybe even that is too much, you can also build these yourself). The adapter will take the gamecard slot though (the gamecard interface is close enough to regular SD/MMC to make this possible, the memory card slot is a whole another thing entirely) so if you're interested in playing official Vita games you need to dump the gamecards and play the dumps. Even big cards work. I'm using a 128 GB card, I know 256 GB cards also work and there's probably no reason why the new 400 or 512 GB cards wouldn't work too. I'm not up to date on the latest developments in Vita hacking, but you may need a small official card for installing the hacks though, at least on the old OLED Vita. 3. In games which support proper analog controls it's not as good as a big home console pad but it's reasonable. I think the touchscreen is underutilized. I've tried the official Duke3D port (Megaton Edition, no longer available from the store though with nothing to replace it) and it plays reasonably well, but why not let the player switch to any weapon quickly just like on PC using the touchscreen? 4. This one I can't really answer because I play so little Doom nowadays :( I guess any map which just says it needs "Boom" or "MBF" (which is what some "Boom-compatible" maps really require) compatibility.
  10. xttl

    Doom Clone "Gloom" Source Code Available!

    IMO Alien Breed 3D (the first one) is the only one of the Amiga "Doom clones" which is actually a good game, at least of the ones I've tried which include Gloom, AB3D, AB3D2, Fears and Breathless. It is at least somewhat entertaining to play, I really liked it the first time I tried it in my life (this was well into the 2010s already), I was visiting a friend of mine who was just bought an A1200 with an upgraded CPU and thought we should try some games on it that never worked on a 500 or 600, and yeah he almost had to make me leave the house that evening. Some months later I almost played it to completion on UAE. IIRC some reviewer once wrote that it is the most "Doom-like" of them in gameplay. Maybe that's why? Too bad that it only supports one extremely low resolution graphics mode intended to run acceptably on A1200s without a beefy CPU or video upgrade. Source code (at least partial?) was released alongside AB3D2's sources but it is written 100% in M68K assembly. Apparently, in the 1990s the author originally planned to release an updated version using AB3D2's engine which supports high resolution video modes but unfortunately that never came to pass. (first post in a long while!)
  11. Why is everyone talking about and criticizing "vanilla controls" when vanilla always came with setup.exe starting from the first release ever? Always-run mode never was officially supported though and that certainly sucked once you started learning how to really play this game. Some people also hated (and still hate) how you can't disable moving forward/backward from mouse but at least I learned to use it somewhat effectively. Nowadays I mostly play with novert though. If we go into the other games using Doom's engine which added looking up/down I'd say having no freelook out of the box sucks.
  12. So I guess it's ok to double/triplepost in threads like this here, at least if it's been a while since my last own post? (been looking at the Shadowcaster RE thread going on under EE) Anyway I got a bit sidetracked again, but now I finally made a working tilemap viewer up (the window size is fixed, tile scaling is fixed and it's not very pretty code at all but at least it somewhat works...). I tried to add some code to display all objects from the spawn list data on top of the tilemap as rectangles but it's not working quite right yet... some (but not all) objects are drawn in wrong positions. I already read from the MacWolf source that for eg. doors the x/y coordinates in the spawnlist point to the target tile, but for some things such as enemies the x/y values are instead supposed to be the integer part of a 8.8 fixed point number (the final game world coordinate where the object is spawned) but maybe the spawn IDs are different on Jaguar or I just didn't get something else right yet, heh. I think I should try to get everything from the spawnlist show up correctly first before even attempting to parse and draw nodes/segs info.
  13. Today I'm continuing work on this. (yeah... I haven't been doing anything at all related to this since the last post :) I just coded a simple wall texture viewer and tilemap viewer using C and SDL2, I'll have to go through the tile graphics and see which tile number maps to which texture and add that information to the map viewer. The eventual goal is to add a nodes viewer to it. Btw. there is only one version of each wall texture, so unlike PC Wolf3D it's using colormapping for the darker walls. EDIT: Oh yeah, the wall texture format is similar to JagDoom in case anybody's interested. They're raw 128*128 pixel paletted images rotated 90 degrees (column-major format). First palette from RGBPALS works well (the RGB palette format is of course uint8_t r,g,b). I haven't checked this yet but I'd guess CRYPALS has the same palettes but in CRY color values instead of RGB.
  14. xttl


    Windows 10 has some great new stuff, for example the console finally works on the same level that xterm worked in the 1980s or so. You can finally resize the window freely using the mouse and ANSI control code support has been improved a lot. The Linux binary compatibility layer (WSL, or "Bash on Windows" which is a really stupid marketing name for it) already works well even though it's still officially in beta. I haven't done my own precise measurements but I think it might also be slightly better with regards to battery life compared to running Windows 7 on the same laptop. It would make sense because mobile is what they're concentrating on now much more than desktops. Too bad about all the UI downgrades since Windows 7 (well depending on whom you ask, they've been downgrading the UI since XP, 2k or NT4 :) but there have been upgrades on this front too (there's this handy menu for keyboarders you get by pressing Win+X that was added in 8 or 8.1 for example). And really fuck the forced updates (though you can avoid them by disabling Windows Update service completely, at least for now...), Windows store junk, Cortana, telemetry (maybe sending some diagnostic information back to MS isn't that bad after all but you should still be able to opt out of it) and advertisement junk, and MS cloud tie-in junk. At least you can disable pretty much all of this if you can get the Enterprise or Education version somehow (like through work or school). Enterprise users can even get LTSB releases that are supported for 10 years and only receive critical security updates during that time, and don't include Cortana, UWP apps or Windows store related junk at all. Unfortunately MS has now decided that newer hardware will not be supported on old LTSB releases (and they won't be releasing these every year or even every other year, previous was 2016 LTSB and next will likely be 2019 LTSB) either similar to how they killed support for new CPUs under Win7 and 8.1. So I'm probably still going to dump Windows completely at some point because it's not like I really need to get to play the latest AAA game releases on the first week or even year they're out anymore. Maybe I got old or something?
  15. xttl

    PSX Doom HD cover art?

    I still couldn't get hold a good camera so here's a quick shot taken with my cellphone which has a really, really bad camera. Seems that it didn't come out that bad after all though. And yeah, the CD holder is broken. :( I guess it got broken in transit from US to FI (either that or the seller was an asshole). If somebody sacrificed their ridged plastic longbox copy I'd say they could get a slightly better quality scan from this than from the CD sized cases (but they'd have to fix the gaps). I could maybe do it to this box if I can ever find another one in better condition for a good price (not over $40 which is what it is on eBay nowadays). Probably not going to happen because I live in PAL land.