Damnation Posted March 27 Share Posted March 27 Oh hey, the forums are back! Link to comment Share on other sites More sharing options...
PPeti66x Posted March 27 Share Posted March 27 @Dietmar WinXP SP3 really works on 486 CPU? It does not requires Pentium1 CPU or Overdrive CPU (P1 CPU in 486-compatible casing)? About the problems around PCI cards: be prepared, that most of modern PCI cards will not work (it will be undetected), because your mainboard/BIOS does not supports later PCI specifications (PCI v2.3 / v3.0?). And these informations are mostly unknown about PCI cards. Some new cards are backward compatible, but many of them are not. I had similar problem with my P-1 and USB 2.0 card. Link to comment Share on other sites More sharing options...
Dietmar Posted March 27 Share Posted March 27 (edited) @PPeti66x Hi, until now not. But when I take a look at the Source Code from XP SP1 or even XP bit64, there is in each a file with name slist.asm. The 64bit version is from 2000, same author. But 64bit slist.asm takes another way, not using cmpxchg8b. If this opcodes from 64bit can be translated into x86 code, this would be also a possibility. But I have no idea, how to reach this in Hex code. It is unchanged since 1996 for NT4. "Only" the opcode cmpxchg8b has to be simulated with opcode from 486 cpu. Cutler in 1996 and so also for XP SP1 solved this problem, just "jump" over this opcode during assembly for .386 (and not .586). I make a try with 90 90 90 90 for all apearance of this opcode in XP SP3 in ntoskrnl.exe. But Bsod. Strange, because also in XP SP3 there is exact the same code from Cutler used from 1996, as you can see in ntoskrnl.exe via Ida Pro. It is a heavy memory operation and with more than 1 cpu there can be problems with this "jump". But the 486 cpu has only 1 processor, so it may be possible Dietmar EDIT: With Windbg, starting with bu ExInterlockedFlushSList I come to its driver entry point of my modded driver. And via trace (t, F8) I can see, that the code in my modded driver was fully entered and left with retn, no Bsod. slist.asm XP SP1 title "Interlocked Support" ;++ ; ; Copyright (c) 1996 Microsoft Corporation ; ; Module Name: ; ; slist.asm ; ; Abstract: ; ; This module implements functions to support interlocked S-List ; operations. ; ; Author: ; ; David N. Cutler (davec) 13-Mar-1996 ; ; Environment: ; ; Any mode. ; ; Revision History: ; ;-- .386p .xlist include ks386.inc include callconv.inc ; calling convention macros include mac386.inc .list _TEXT$00 SEGMENT DWORD PUBLIC 'CODE' ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING page , 132 subttl "Interlocked Flush Sequenced List" ;++ ; ; PSINGLE_LIST_ENTRY ; FASTCALL ; RtlpInterlockedFlushSList ( ; IN PSINGLE_LIST_ENTRY ListHead ; ) ; ; Routine Description: ; ; This function removes the entire list from a sequenced singly ; linked list so that access to the list is synchronized in an MP system. ; If there are no entries in the list, then a value of NULL is returned. ; Otherwise, the address of the entry at the top of the list is removed ; and returned as the function value and the list header is set to point ; to NULL. ; ; Arguments: ; ; (ecx) = ListHead - Supplies a pointer to the sequenced listhead from ; which the list is to be flushed. ; ; Return Value: ; ; The address of the entire current list, or NULL if the list is ; empty. ; ;-- ; ; These old interfaces just fall into the new ones ; cPublicFastCall ExInterlockedFlushSList, 1 fstENDP ExInterlockedFlushSList cPublicFastCall RtlpInterlockedFlushSList, 1 cPublicFpo 0,1 ; ; Save nonvolatile registers and read the listhead sequence number followed ; by the listhead next link. ; ; N.B. These two dwords MUST be read exactly in this order. ; push ebx ; save nonvolatile registers push ebp ; xor ebx, ebx ; zero out new pointer mov ebp, ecx ; save listhead address mov edx, [ebp] + 4 ; get current sequence number mov eax, [ebp] + 0 ; get current next link ; ; N.B. The following code is the retry code should the compare ; part of the compare exchange operation fail ; ; If the list is empty, then there is nothing that can be removed. ; Efls10: or eax, eax ; check if list is empty jz short Efls20 ; if z set, list is empty mov ecx, edx ; copy sequence number mov cx, bx ; clear depth leaving sequence number .586 ifndef NT_UP lock cmpxchg8b qword ptr [ebp] ; compare and exchange else cmpxchg8b qword ptr [ebp] ; compare and exchange endif .386 jnz short Efls10 ; if z clear, exchange failed ; ; Restore nonvolatile registers and return result. ; cPublicFpo 0,0 Efls20: pop ebp ; restore nonvolatile registers pop ebx ; fstRET RtlpInterlockedFlushSList fstENDP RtlpInterlockedFlushSList page , 132 subttl "Interlocked Pop Entry Sequenced List" ;++ ; ; PVOID ; FASTCALL ; RtlpInterlockedPopEntrySList ( ; IN PSLIST_HEADER ListHead ; ) ; ; Routine Description: ; ; This function removes an entry from the front of a sequenced singly ; linked list so that access to the list is synchronized in an MP system. ; If there are no entries in the list, then a value of NULL is returned. ; Otherwise, the address of the entry that is removed is returned as the ; function value. ; ; Arguments: ; ; (ecx) = ListHead - Supplies a pointer to the sequenced listhead from ; which an entry is to be removed. ; ; Return Value: ; ; The address of the entry removed from the list, or NULL if the list is ; empty. ; ;-- ; ; These older interfaces just fall into the new code below ; cPublicFastCall InterlockedPopEntrySList, 1 fstENDP InterlockedPopEntrySList cPublicFastCall ExInterlockedPopEntrySList, 2 fstENDP ExInterlockedPopEntrySList cPublicFastCall RtlpInterlockedPopEntrySList, 1 cPublicFpo 0,2 ; ; Save nonvolatile registers and read the listhead sequence number followed ; by the listhead next link. ; ; N.B. These two dwords MUST be read exactly in this order. ; push ebx ; save nonvolatile registers push ebp ; mov ebp, ecx ; save listhead address ; ; N.B. The following code is the continuation address should a fault ; occur in the rare case described below. ; public ExpInterlockedPopEntrySListResume public _ExpInterlockedPopEntrySListResume@0 ExpInterlockedPopEntrySListResume: ; _ExpInterlockedPopEntrySListResume@0: ; mov edx,[ebp] + 4 ; get current sequence number mov eax,[ebp] + 0 ; get current next link ; ; If the list is empty, then there is nothing that can be removed. ; Epop10: or eax, eax ; check if list is empty jz short Epop20 ; if z set, list is empty lea ecx, [edx-1] ; Adjust depth only ; ; N.B. It is possible for the following instruction to fault in the rare ; case where the first entry in the list is allocated on another ; processor and free between the time the free pointer is read above ; and the following instruction. When this happens, the access fault ; code continues execution by skipping the following instruction. ; This results in the compare failing and the entire operation is ; retried. ; public ExpInterlockedPopEntrySListFault ExpInterlockedPopEntrySListFault: ; mov ebx, [eax] ; get address of successor entry public _ExpInterlockedPopEntrySListEnd@0 _ExpInterlockedPopEntrySListEnd@0: ; .586 ifndef NT_UP lock cmpxchg8b qword ptr [ebp] ; compare and exchange else cmpxchg8b qword ptr [ebp] ; compare and exchange endif .386 jnz short Epop10 ; if z clear, exchange failed ; ; Restore nonvolatile registers and return result. ; cPublicFpo 0,0 Epop20: pop ebp ; restore nonvolatile registers pop ebx ; fstRET RtlpInterlockedPopEntrySList fstENDP RtlpInterlockedPopEntrySList page , 132 subttl "Interlocked Push Entry Sequenced List" ;++ ; ; PVOID ; FASTCALL ; RtlpInterlockedPushEntrySList ( ; IN PSLIST_HEADER ListHead, ; IN PVOID ListEntry ; ) ; ; Routine Description: ; ; This function inserts an entry at the head of a sequenced singly linked ; list so that access to the list is synchronized in an MP system. ; ; Arguments: ; ; (ecx) ListHead - Supplies a pointer to the sequenced listhead into which ; an entry is to be inserted. ; ; (edx) ListEntry - Supplies a pointer to the entry to be inserted at the ; head of the list. ; ; Return Value: ; ; Previous contents of ListHead. NULL implies list went from empty ; to not empty. ; ;-- ; ; This old interface just fall into the new code below. ; cPublicFastCall ExInterlockedPushEntrySList, 3 pop [esp] ; Drop the lock argument fstENDP ExInterlockedPushEntrySList cPublicFastCall InterlockedPushEntrySList, 2 fstENDP InterlockedPushEntrySList cPublicFastCall RtlpInterlockedPushEntrySList, 2 cPublicFpo 0,2 ; ; Save nonvolatile registers and read the listhead sequence number followed ; by the listhead next link. ; ; N.B. These two dwords MUST be read exactly in this order. ; push ebx ; save nonvolatile registers push ebp ; mov ebp, ecx ; save listhead address mov ebx, edx ; save list entry address mov edx,[ebp] + 4 ; get current sequence number mov eax,[ebp] + 0 ; get current next link Epsh10: mov [ebx], eax ; set next link in new first entry lea ecx, [edx+010001H] ; increment sequence number and depth .586 ifndef NT_UP lock cmpxchg8b qword ptr [ebp] ; compare and exchange else cmpxchg8b qword ptr[ebp] ; compare and exchange endif .386 jnz short Epsh10 ; if z clear, exchange failed ; ; Restore nonvolatile registers and return result. ; cPublicFpo 0,0 pop ebp ; restore nonvolatile registers pop ebx ; fstRET RtlpInterlockedPushEntrySList fstENDP RtlpInterlockedPushEntrySList ;++ ; ; SINGLE_LIST_ENTRY ; FASTCALL ; InterlockedPushListSList ( ; IN PSLIST_HEADER ListHead, ; IN PSINGLE_LIST_ENTRY List, ; IN PSINGLE_LIST_ENTRY ListEnd, ; IN ULONG Count ; ) ; ; Routine Description: ; ; This function will push multiple entries onto an SList at once ; ; Arguments: ; ; ListHead - List head to push the list to. ; ; List - The list to add to the front of the SList ; ListEnd - The last element in the chain ; Count - The number of items in the chain ; ; Return Value: ; ; PSINGLE_LIST_ENTRY - The old header pointer is returned ; ;-- cPublicFastCall InterlockedPushListSList, 4 cPublicFpo 0,4 push ebx ; save nonvolatile registers push ebp ; mov ebp, ecx ; save listhead address mov ebx, edx ; save list entry address mov edx,[ebp] + 4 ; get current sequence number mov eax,[ebp] + 0 ; get current next link Epshl10: mov ecx, [esp+4*3] ; Fetch address of list tail mov [ecx], eax ; Store new forward pointer in tail entry lea ecx, [edx+010000H] ; increment sequence number add ecx, [esp+4*4] ; Add in new count to create correct depth .586 ifndef NT_UP lock cmpxchg8b qword ptr [ebp] ; compare and exchange else cmpxchg8b qword ptr[ebp] ; compare and exchange endif .386 jnz short Epshl10 ; if z clear, exchange failed cPublicFpo 0,0 pop ebp ; restore nonvolatile registers pop ebx ; fstRET InterlockedPushListSList fstENDP InterlockedPushListSList ;++ ; ; PSINGLE_LIST_ENTRY ; FirstEntrySList ( ; IN PSLIST_HEADER SListHead ; ) ; ; Routine Description: ; ; This function returns the address of the fisrt entry in the SLIST or ; NULL. ; ; Arguments: ; ; ListHead (rcx) - Supplies a pointer to the sequenced listhead from ; which the first entry address is to be computed. ; ; Return Value: ; ; The address of the first entry is the specified, or NULL if the list is ; empty. ; ;-- cPublicProc _FirstEntrySList, 1 cPublicFpo 1,0 mov eax, [esp+4] mov eax, [eax] stdRET _FirstEntrySList stdENDP _FirstEntrySList ;++ ; ; LONGLONG ; FASTCALL ; RtlInterlockedCompareExchange64 ( ; IN OUT PLONGLONG Destination, ; IN PLONGLONG Exchange, ; IN PLONGLONG Comperand ; ) ; ; Routine Description: ; ; This function performs a compare and exchange of 64-bits. ; ; Arguments: ; ; (ecx) Destination - Supplies a pointer to the destination variable. ; ; (edx) Exchange - Supplies a pointer to the exchange value. ; ; (esp+4) Comperand - Supplies a pointer to the comperand value. ; ; Return Value: ; ; The current destination value is returned as the function value. ; ;-- cPublicFastCall RtlInterlockedCompareExchange64, 3 cPublicFpo 0,2 ; ; Save nonvolatile registers and read the exchange and comperand values. ; push ebx ; save nonvolatile registers push ebp ; mov ebp, ecx ; set destination address mov ebx, [edx] ; get exchange value mov ecx, [edx] + 4 ; mov edx, [esp] + 12 ; get comperand address mov eax, [edx] ; get comperand value mov edx, [edx] + 4 ; .586 ifndef NT_UP lock cmpxchg8b qword ptr [ebp] ; compare and exchange else cmpxchg8b qword ptr[ebp] ; compare and exchange endif .386 ; ; Restore nonvolatile registers and return result in edx:eax. ; cPublicFpo 0,0 pop ebp ; restore nonvolatile registers pop ebx ; fstRET RtlInterlockedCompareExchange64 fstENDP RtlInterlockedCompareExchange64 _TEXT$00 ends end Edited March 27 by Dietmar Link to comment Share on other sites More sharing options...
Dietmar Posted March 27 Share Posted March 27 (edited) I think, this is a crazy nice way to overcome this problem, that works on all cpu. Problem is only the translate from AMD64 with 64bit registers this opcode to x86 (486 cpu) with 32 bit registers. I think, it can be done Dietmar For bit64 mov rax, [rcx] ; get address, sequence, and depth and rax, 0fe000000H ; isolate packed address ; ; The following code takes advantage of the fact that the high order bit ; for user mode addresses is zero and for system addresses is one. ; ifdef NTOS_KERNEL_RUNTIME cmp rax, 1 ; set carry if address is zero cmc ; set carry if address is not zero rcr rax, 1 ; rotate carry into high bit sar rax, 63 - 43 ; extract first entry address else shr rax, 63 - 42 ; extract first entry address endif ret ; return Edited March 27 by Dietmar Link to comment Share on other sites More sharing options...
Dietmar Posted March 27 Share Posted March 27 For the 486 cpu, this AMD64 opcode will look something like this Dietmar 8B 01 ; mov eax, [ecx] 25 00 00 00 FE ; and eax, 0fe000000H #ifdef NTOS_KERNEL_RUNTIME 80 38 01 ; cmp byte ptr [eax], 1 F6 D1 ; not cl D1 C2 ; ror eax, 1 C1 F8 2B ; sar eax, 43 #else C1 F8 2A ; sar eax, 42 #endif C3 ; ret Link to comment Share on other sites More sharing options...
PPeti66x Posted March 27 Share Posted March 27 @Dietmar But the cmpxchg8b is probably used in many system files and drivers, so you must patch probably hundreds or thousands of files. (0F C7 4D 00 pattern found in ntdll.dll, duser.dll and some others, not only in ntoskernel, and there are more variants). Link to comment Share on other sites More sharing options...
Dietmar Posted March 28 Share Posted March 28 (edited) @PPeti66x A nice solution for this would be, when at the moment, when opcode for cmpxchg8b is asked from a file for the 486 cpu, that there is something like a tender between the opcode and the cpu, that makes exact the same operations on all the registers, that cmpxchg8b is doing. It would be like a software simulation for cmpxchg8b direct before the cpu. The program for this can be done in C language. I will call it 486.dll . At once, such an XP would work on 386, 486 586 686 cpu with all functionality. And once it has been done one time, crazy work, other unknown opcodes for other cpu can be done the same way. Dietmar PS: @Mov AX, 0xDEAD I remember, that you have a tool, that can check, if 2 binaries are doing the same. Edited March 28 by Dietmar Link to comment Share on other sites More sharing options...
gordo999 Posted March 29 Share Posted March 29 On 2/24/2024 at 5:03 PM, SEDANEH said: Because Windows XP does not support Nvidia graphics above 1000 series. I had XP running on a GT 1030 but only in super-VGA mode. I have a GT 730 but it has disappeared under mounds of equipment...can't find it. Now, when I try to start XP on the same Asus B360, I get a black screen for a long time and sometimes it BSODs after 5 or 10 minutes. I was too slow to get the error code but it is display related. I am trying to repeat the BSOD but all I have is a black screen. Oddly, I get the XP welcome screen but it does not reach logon. Any ideas? Also, I can no longer get W7 running on the B360 machine because I re-installed the USB driver for my new B760 and erased the A36D identifier for the older machine. I am looking for a way to re-install the old hardware ID but I can't even find INFfile for it. Link to comment Share on other sites More sharing options...
Damnation Posted March 29 Share Posted March 29 @gordo999 Bricked XP install probably. Link to comment Share on other sites More sharing options...
gordo999 Posted March 29 Share Posted March 29 1 hour ago, Damnation said: @gordo999 Bricked XP install probably. Could be. I have not touched the disk for a while and it worked last time I tried it. Also, for some reason I made a clone backup of the installation on another hard drive. It doesn't work either. Rust!!! :-) Link to comment Share on other sites More sharing options...
Dietmar Posted March 29 Share Posted March 29 I cant post in XP running on 486 cpu Dietmar Link to comment Share on other sites More sharing options...
PPeti66x Posted March 29 Share Posted March 29 @Dietmar I think, the image loader part of the kernel must be hacked to do that. But the task itself is not so easy. The long jump is 5 bytes, the cmpxchg8b is 4 bytes, so we need to recognize and preserve the next instruction. I have no idea, how to do that. Link to comment Share on other sites More sharing options...
gordo999 Posted March 30 Share Posted March 30 25 minutes ago, PPeti66x said: @Dietmar I think, the image loader part of the kernel must be hacked to do that. But the task itself is not so easy. The long jump is 5 bytes, the cmpxchg8b is 4 bytes, so we need to recognize and preserve the next instruction. I have no idea, how to do that. You'd need a code cave nearby where you could access it with a jmp instruction, then write your new code and return to the next instruction. 1 Link to comment Share on other sites More sharing options...
pappyN4 Posted March 30 Share Posted March 30 1 hour ago, PPeti66x said: @Dietmar I think, the image loader part of the kernel must be hacked to do that. But the task itself is not so easy. The long jump is 5 bytes, the cmpxchg8b is 4 bytes, so we need to recognize and preserve the next instruction. I have no idea, how to do that. Something like this maybe? Red/Blue is existing code, Green is extra code to be added but not enough space. So Black to jump to free spot, add code, then return from. As long as there is enough space for jump command and location to jump to a free spot. 1 Link to comment Share on other sites More sharing options...
gordo999 Posted April 1 Share Posted April 1 On 3/29/2024 at 2:24 AM, Damnation said: @gordo999 Bricked XP install probably. @Damnation ...Is the old thread around where we can discuss XP in general? I don't want to hijack @Dietmar 's thread. Part of my problem was brain-deadness. When I tried to run W7 on my old B360, I forgot to add the hardware ID to the INF file. Duh!!! Have not verified yet but the XP issue may be related to the video driver. I had it running before on a GT 1030 in SVGA mode at high resolution and that worked fine for me. Thought it might be an HDMI/DVI issue but it did not work either on the onboard Intel video driver using a D-type connector. I don't think XP is bricked. I have been able to run it fine up to the intro screen. Replacing the BIOS got W10 running again and I don't want to try XP again in case it causes the same issue. Trying to understand why it would. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now