xoreaxeaxeax / sandsifter

The x86 processor fuzzer
BSD 3-Clause "New" or "Revised" License
4.89k stars 349 forks source link

Run on 80386 Debian within emulator? #61

Open superfury opened 6 years ago

superfury commented 6 years ago

I'm currently having some problems with some unknown x86(80386/80486) instructions within my emulator(UniPCemu, it's on bitbucket). Is it possible to run this within my emulator somehow? Currently only MS-DOS 5.0 and below run correctly. Setup of it crashes, newer versions crash, Windows 95 setup crashes, Megarace runs mostly(except from CD-ROM), FDC is buggy due to an unknown CPU error(it matches the documentation(80386 user programmer's reference html webpages) appendix A, though, but the Compaq Deskpro 386 starts double seeking due to a CPU bug). One 8086 app hangs(california games), while many others run(the secret of monkey island, ultima 6, 8088MPH(except slightly buggy IBM vectorball output producing noise in the background and credits crashing due to SMC with inaccurate clocks vs real 8088)). Can this program somehow help me find those bugs? Edit: Also DLX Linux 10MB image from Bochs website seems to crash with "L 04 04 04 04" 04 repeating infinitely.

superfury commented 6 years ago

Just recently fixed a bug within the POP ES 32-bit instruction(32-bit operand-size POP-ES), which incremented/decremented the (E)SP value with 2 instead pf the proper 4.

Having fixed this issue(although known Linux won't get past the L of the LILO boot loader, Windows 3.0 kernel boot process hangs and Windows 95 setup jumps into uninitialized RAM(containing zeroed RAM)), I've managed to get Minix 2.0.4 booting from MS-DOS 5.0 using the boot.com program.

Anyone knows how to install the sandsifter on Minix 2.0.4(without internet) from within Dosbox? If I can manage install it within Dosbox's 80386/80486 emulation, I can hopefully finally audit my 80386/80486 emulation for the unknown bugs that have been there till now.

Anyone knows how to install this on Minix 2.0.4(50MB disk image)?

jackson2k2 commented 6 years ago

I don't think Minix 2.0.4 would have anything necessary to run modern versions of Python or Capstone.

superfury commented 5 years ago

Can sandsifter be ran from a older linux distro that can be installed and ran on a 80386(Compaq Deskpro 386)? I've tried installing a old Debian distro that's supposed to be compatible(according to https://hackaday.com/2011/08/12/installing-linux-on-a-386-laptop/ ), but loadlin aborts reporting memory issues(not enough memory if I remember correctly)?

The used distro is Debian 1.3.1. Edit: Just tried again on the current build. Loadlin succeeds and now loads two files, then it clears the screen and says "Uncompressing Linux...done. Now booting the kernel ".

So that's partway booting at least :D

I do see a lot of single-step traps though(INT1 caused by trap flag). Eventually, I see a #GP(666C) fault being raised on loading a segment selector 666F on 0010:0010AD09? Anyone knows if that's correct? Edit: Eventually I see an #UD FFFF instruction being executed during boot? I don't think that's supposed to happen(together with the many #GP faults being raised)?

superfury commented 5 years ago

Having copied fresh files from said links to the disk image, now it runs a bit further, before crashing with fatal errors and displaying a stack trace: partial list of call traces.zip 987-starting debian

superfury commented 5 years ago

Is there any way to step through the linux kernel(and accompanying c source code) during the boot process? It must be an old one(this one is 2.0.33), since it'll need to run on a 80486SX(80386 loadlin somehow fails, telling not enough memory to load(reporting RAM correctly(4MB(3MB extended)) on the 80386 emulation) that's emulated.

Anyone? My host PC is running Windows 10(don't have linux on the host).

superfury commented 5 years ago

I've implemented some more functionality by now. It's now supposed to capable of running as a i586/Pentium (although without the Machine Check Exception(is it mandatory?) and FPU). Afaik, Linux can use the CPU's mechanism(present since the 80286 generation?) to emulate a FPU, so that should be covered?

Any ideas on Linux operating systems and applications etc. to install on it and run Sandsifter? The hardware itself is still using the basic Compaq Deskpro 386 architecture.

superfury commented 5 years ago

I managed to get my first Linux distro running inside my emulator! Now it at least runs what seems to be Slackware 1.02(according to http://openskill.info/topic.php?ID=157). It's the old Slackware distro at http://www.qemu-advent-calendar.org/2014/ , day #1. I simply converted the qcow2 image to a flat .img file, then mounted it into my emulator as a Bochs CHS-style image(by adding a .img.bochs.txt file to the .img file to indicate that).

Is it possible to run this Sandsifter on that linux distro? Edit: Btw, at least older distros(Linux 0.01) still seem to crash in UniPCemu, while newer distros (at least tried Debian 1.x.x (the oldest one I could find an installation CD-ROM of, as far as I can remember it's version 1.3.something). It immediately crashes on those newer distros (newer linux versions) when starting up after decompressing the kernel.

Anyone knows something about that?

superfury commented 4 years ago

After fixing various bugs in the CPU(regarding segmentation and conforming code segments(not erroring out when transferring control to them and applying data-segment privilege rules for them when loading into data segment registers), the "POP [(E)SP(+*)]" using incorrect addresses((E)SP as it was before executing the instruction instead of after increasing (E)SP by 2 or 4 to write it's result and incorrect MOV to a memory address after a exception by a MOV [imm16/32],AL/AX/EAX causing the MOV to use the [imm16/32] from that last faulted MOV [imm16],AL/AX/EAX instead(a particularly hidden implementation bug)), I finally managed to get Debian 1.3.1 installed and booting! :D

(Although the setup program seemed to have troubles with the second CD-ROM drive on the secondary ATA slave when not mounted, reporting "hdd : drive not ready or tray open" a few times, followed by a "hdd : " error saying that the status was 0x48(the drive itself being ready to transfer data back to the cpu as a part of the ATAPI command) during each and every block access?)

Can Sandsifter run on Debian 1.3.1(Pentium-compatible CPU emulation with no hardware FPU nor Machine Check Exceptions(Essentially a Nexgen nx586 reporting as a Pentium in the CPUID))? Or does it have a higher minimum requirement?

superfury commented 4 years ago

The exact errors during setup were(after ejecting the disk while running it and selecting an option):

hdd : tray open or drive not ready
hdd : tray open or drive not ready
hdd : tray open or drive not ready
hdd : tray open
end_request: I/O error, dev 16:40, sector 3
.hdd: unexpected_intr: status=0x41
hdd: unexpected_intr: error=0x60
superfury commented 4 years ago

I have since changed the CD-ROM emulation somewhat(based on Windows 95 RTM behaviour and issues with it). Perhaps the errors might be gone during the Debian setup now, but they might still be there(haven't checked yet). One of the most important things changed is the ATAPI packet command being started to have improved effects on the device's state.

Some of the things changed with the CD-ROM drives:

There also have been various CPU bugfixes and improvements(regarding segmentation limits being applied better now as well as a bugfix in the MOV instructions that were causing the MOV to a modr/m memory address to use the last address of a MOV [imm16/32],AL/AX/EAX instead. :S Also just recently found out that the CPU mask for wrapping memory addresses to 16-bit or 32-bit offsets(e.g. producing a 32-bit offset after adding e.g. EAX+disp8 by wrapping with 0xFFFFFFFF(32-bit) or 0xFFFF(16-bit) using a simply AND operation) was behaving incorrectly with the 32-bit one. Since it's stored in a 64-bit variable(uint64_t type) and the compiler somehow seems to thing that 0xFFFFFFFF is an signed int(which is strange in and of itself?), it was sign-extending it to 0xFFFFFFFFFFFFFFFF, thus making the mask become ineffective. So addressing a dword at 0xFFFFFFFF+01h would check the memory access against 0x100000000 through 0x100000003 against the 32-bit limits(0-4GB) and throw a #GP/#SS fault, instead of properly wrapping it to addresses 0-3 and not faulting as it should have done in the first place. Of course, the wrapping only applies to addresses that are calculated as effective addresses, not to the seperated bytes of e.g. a word/dword access in memory itself. So when the mask would end up at 0xFFFFFFFD and up with a dword memory access, it will still actually validate it against 0xFFFFFFFD-0x100000000, where the 0x100000000 byte of the access would throw a #GP/#SS fault as it should.

superfury commented 4 years ago

So now, Debian (version 1.3.1) is running properly inside UniPCemu(installed from a CD-ROM disc image).

Anyone knows how to get Sandsifter installed on it? Stuff like Winimage can't seem to inject anything into the image(it's read-only for all linux-based images)?

Edit: Perhaps through a ISO disc image? But how would I go about installing the requirements(capcom is a simple pull from the github repo, so is Sandsifter. But how do I install Python on it from an ISO image?)?

Kaspi314 commented 3 years ago

I recommend you figure out how to compile a modern GCC on the system (bootstrap a compiler) and compile (modern) linux from scratch (patching in whatever drivers you might need)

It is probably a lot of work.

superfury commented 3 years ago

Just managed to get Baresifter's 32-bit version running from a floppy on UniPCemu's Pentium II emulation (See https://www.vogons.org/viewtopic.php?p=977883#p977883 )! Although it should be able to go as low as a 486SX afaik. It's Baresifter with x64-specific checks removed in main.c and my fix mentioned in https://github.com/blitz/baresifter/issues/4 for non-NX compatible processors. It's currently sifting (after fixing a bug in UniPCemu giving the 'wrong' CR2 addresses for doubleword page faults(which caused it to fault on address n+3 instead of n+1 or n+2 when supposed to be faulting on the second or third byte of the doubleword). :D