Jump to content

I am trying to create an extended kernel for NT4


Recommended Posts

 I'm trying to create an extended kernel for NT4, but I'm having trouble finding the real base Address :(.
The reason for searching for the new base address I know is because I got this error after adding function:

 930883327_1yZFiRxp(1).png.c50f7882deb68da612a4b290385bc3db.png
I was able to get Memory.dmp by running nt4 on an old real computer but I couldn't find the real base Address. I tried entering the base address ollyDumpEX specified for me but it didn't work :

 Captur66e.thumb.PNG.ea883152139b40bcbf73310521c5c825.PNG ,

but the error changed :

 20.png.b9b04207c6e6b5c308942d0d8bd7708f.png

kernel32 can not relocate address, so if i move it to the working address , it goes BSoD , at first , kernel32 use critial base address, so it goes BSoD suddenly. at next kernel32 use bad base address so it tried to move address , but kernel32 does not allow relocate address , so it shows such BSoD.

I think the range of the addresses not to use for Kernel32.dll.

Dealing with NT4 is difficult and it is not as easy to handle with it unlike 2000 and XP. But I am really surprised how @junior600 finds the real base Address .

He was saying he's working on CFFexplorer like I do !

Edited by windows2
Link to comment
Share on other sites


I suspect that the new section should be before .reloc because when creating a new section ".xdata" in my case, the ntdll.dll clause is broken meaning that the ntdll.dll  it needs to be relocated. Who knows an app that can create a new section before .reloc

Link to comment
Share on other sites

Hi Windows2

1) MS rebases all critical system .dlls to avoid overlapping ranges, you can rebase too using 3rd utils (pe_rebaser from PEBLISS project) or rebase.exe from leaked XP/W2003 sources

2) No matter how sections ordered, just assign new section to new mem range, example kernel32 from NT4 Service Pack 6, base adress 77F00000

.text 77F01000

.rdata 77F3C000

.data 77F45000

.rsrc 77F47000

.reloc 77F5B000, size 2E00

Free range starts at 77F5B000+2E00=77F5DE00 Unfortunately this range probably will be assigned to next system dll like user32.dll. If you need more mem range, you need to find enough gap between DLLs and rebase kernel32 to new adress

For XP couple years ago i find holes with bat file:

basic_info_viewer.exe     c:\WINDOWS\system32\1033\dwintl.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1033\vsjitdebuggerui.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1cfgmgr32.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1winsta.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\6to4svc.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\a3d.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\aaaamon.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\aaclient.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\ac3api.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\acctres.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\acledit.dll    >> c:\dllbase.txt

...all remain dll in system32....

generated dllbase.txt:

c:\WINDOWS\system32\1033\dwintl.dll Image base: 0x314c0000 Len: 0xc000
c:\WINDOWS\system32\1033\vsjitdebuggerui.dll Image base: 0x3b3f0000 Len: 0x4000
c:\WINDOWS\system32\1cfgmgr32.dll Image base: 0x74ae0000 Len: 0x7000
c:\WINDOWS\system32\1winsta.dll Image base: 0x76360000 Len: 0x10000
c:\WINDOWS\system32\6to4svc.dll Image base: 0x6bc00000 Len: 0x1d000
c:\WINDOWS\system32\a3d.dll Image base: 0x2000000 Len: 0x12000
c:\WINDOWS\system32\aaaamon.dll Image base: 0x717a0000 Len: 0xa000
c:\WINDOWS\system32\aaclient.dll Image base: 0x6d640000 Len: 0x25000
c:\WINDOWS\system32\ac3api.dll Image base: 0x2000000 Len: 0xf000
c:\WINDOWS\system32\acctres.dll Image base: 0x71780000 Len: 0x12000
c:\WINDOWS\system32\acledit.dll Image base: 0x71b70000 Len: 0x22000
c:\WINDOWS\system32\aclui.dll Image base: 0x71550000 Len: 0x1f000

Import dllbase to excel with splitting every line to 3 cells, name, addr, len. Then sort by addr and look for gaps.Max available address for user mode dll is 8000000 (/3G systems allow above)

3) PE format allow BINDING to hardcoded adresses at compile time, this mean addresses of functions from kernel32 already embedded to other DLLs like 77F23344, you cannot rebase in such case, don't sure how NT4 was compiled, i hope this mode is not used

Link to comment
Share on other sites

On 3/20/2022 at 6:34 PM, Mov AX, 0xDEAD said:

Hi Windows2

1) MS rebases all critical system .dlls to avoid overlapping ranges, you can rebase too using 3rd utils (pe_rebaser from PEBLISS project) or rebase.exe from leaked XP/W2003 sources

2) No matter how sections ordered, just assign new section to new mem range, example kernel32 from NT4 Service Pack 6, base adress 77F00000

.text 77F01000

.rdata 77F3C000

.data 77F45000

.rsrc 77F47000

.reloc 77F5B000, size 2E00

Free range starts at 77F5B000+2E00=77F5DE00 Unfortunately this range probably will be assigned to next system dll like user32.dll. If you need more mem range, you need to find enough gap between DLLs and rebase kernel32 to new adress

For XP couple years ago i find holes with bat file:

basic_info_viewer.exe     c:\WINDOWS\system32\1033\dwintl.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1033\vsjitdebuggerui.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1cfgmgr32.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\1winsta.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\6to4svc.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\a3d.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\aaaamon.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\aaclient.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\ac3api.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\acctres.dll    >> c:\dllbase.txt
basic_info_viewer.exe     c:\WINDOWS\system32\acledit.dll    >> c:\dllbase.txt

...all remain dll in system32....

generated dllbase.txt:

c:\WINDOWS\system32\1033\dwintl.dll Image base: 0x314c0000 Len: 0xc000
c:\WINDOWS\system32\1033\vsjitdebuggerui.dll Image base: 0x3b3f0000 Len: 0x4000
c:\WINDOWS\system32\1cfgmgr32.dll Image base: 0x74ae0000 Len: 0x7000
c:\WINDOWS\system32\1winsta.dll Image base: 0x76360000 Len: 0x10000
c:\WINDOWS\system32\6to4svc.dll Image base: 0x6bc00000 Len: 0x1d000
c:\WINDOWS\system32\a3d.dll Image base: 0x2000000 Len: 0x12000
c:\WINDOWS\system32\aaaamon.dll Image base: 0x717a0000 Len: 0xa000
c:\WINDOWS\system32\aaclient.dll Image base: 0x6d640000 Len: 0x25000
c:\WINDOWS\system32\ac3api.dll Image base: 0x2000000 Len: 0xf000
c:\WINDOWS\system32\acctres.dll Image base: 0x71780000 Len: 0x12000
c:\WINDOWS\system32\acledit.dll Image base: 0x71b70000 Len: 0x22000
c:\WINDOWS\system32\aclui.dll Image base: 0x71550000 Len: 0x1f000

Import dllbase to excel with splitting every line to 3 cells, name, addr, len. Then sort by addr and look for gaps.Max available address for user mode dll is 8000000 (/3G systems allow above)

3) PE format allow BINDING to hardcoded adresses at compile time, this mean addresses of functions from kernel32 already embedded to other DLLs like 77F23344, you cannot rebase in such case, don't sure how NT4 was compiled, i hope this mode is not used

Thank you for all this wonderful information :) . I will try to implement your important tips when I have time. I think that the task takes a lot of time. Unfortunately, the time that was given to me this week did not find a solution to the problem, but I will try in the next time.

Edited by windows2
Link to comment
Share on other sites

I just made a wrapper for kernel32, which called itself kernel32.dll, with the original kernel32 renamed to something else. The benefit of this method is that the original kernel32 is not modified and thus does not change in size, so no rebasing is required. But you would have to know how to use VC++ or a similar IDE (but with VC++ and x86 code, you can very easily do inline assembly).

You will have to export every function the original kernel32 does, and forward it to the original kernel32 (renamed "kernel33" or something similar). To accelerate the process, I wrote an application called "scanexp" (which should run on NT 3.51/95 and up) that scans a list of function names (as in the type of list you would get if you ctrl-a a dll's function list in dependency walker then copied into a txt file) and turns them into pragma directives indicating that they are export forwards. Dependency Walker doesn't grab ordinal-only exports as easily, but if you manually input the numbers they will be enumerated properly as well.

Usage is as follows:

unknown.png
-name of text file with function names
-name of c/cpp file you want to make with the pragma directives
-name of file to export forward to
 

Edited by win32
Link to comment
Share on other sites

5 hours ago, win32 said:

I just made a wrapper for kernel32, which called itself kernel32.dll, with the original kernel32 renamed to something else. The benefit of this method is that the original kernel32 is not modified and thus does not change in size, so no rebasing is required. But you would have to know how to use VC++ or a similar IDE (but with VC++ and x86 code, you can very easily do inline assembly).

You will have to export every function the original kernel32 does, and forward it to the original kernel32 (renamed "kernel33" or something similar). To accelerate the process, I wrote an application called "scanexp" (which should run on NT 3.51/95 and up) that scans a list of function names (as in the type of list you would get if you ctrl-a a dll's function list in dependency walker then copied into a txt file) and turns them into pragma directives indicating that they are export forwards. Dependency Walker doesn't grab ordinal-only exports as easily, but if you manually input the numbers they will be enumerated properly as well.

Usage is as follows:

unknown.png
-name of text file with function names
-name of c/cpp file you want to make with the pragma directives
-name of file to export forward to
 

Well thank you win32 for these important tips and for this great app :) , I will do this when I have the time. I will try to improve my VC++ skills so that I can do this without difficulties.

Link to comment
Share on other sites

  • 1 month later...
On 3/20/2022 at 9:51 PM, win32 said:

I just made a wrapper for kernel32, which called itself kernel32.dll, with the original kernel32 renamed to something else. The benefit of this method is that the original kernel32 is not modified and thus does not change in size, so no rebasing is required. But you would have to know how to use VC++ or a similar IDE (but with VC++ and x86 code, you can very easily do inline assembly).

You will have to export every function the original kernel32 does, and forward it to the original kernel32 (renamed "kernel33" or something similar). To accelerate the process, I wrote an application called "scanexp" (which should run on NT 3.51/95 and up) that scans a list of function names (as in the type of list you would get if you ctrl-a a dll's function list in dependency walker then copied into a txt file) and turns them into pragma directives indicating that they are export forwards. Dependency Walker doesn't grab ordinal-only exports as easily, but if you manually input the numbers they will be enumerated properly as well.

Usage is as follows:

unknown.png
-name of text file with function names
-name of c/cpp file you want to make with the pragma directives
-name of file to export forward to
 

Awesome, is there any chance you can make a YouTube tutorial about how to make the kernel32 wrapper?

Link to comment
Share on other sites

  • 2 months later...
On 3/21/2022 at 5:51 AM, win32 said:

I just made a wrapper for kernel32, which called itself kernel32.dll, with the original kernel32 renamed to something else. The benefit of this method is that the original kernel32 is not modified and thus does not change in size, so no rebasing is required. But you would have to know how to use VC++ or a similar IDE (but with VC++ and x86 code, you can very easily do inline assembly).

You will have to export every function the original kernel32 does, and forward it to the original kernel32 (renamed "kernel33" or something similar). To accelerate the process, I wrote an application called "scanexp" (which should run on NT 3.51/95 and up) that scans a list of function names (as in the type of list you would get if you ctrl-a a dll's function list in dependency walker then copied into a txt file) and turns them into pragma directives indicating that they are export forwards. Dependency Walker doesn't grab ordinal-only exports as easily, but if you manually input the numbers they will be enumerated properly as well.

Usage is as follows:

unknown.png
-name of text file with function names
-name of c/cpp file you want to make with the pragma directives
-name of file to export forward to
 

@win32

https://forum.eclectic4un.me/viewtopic.php?f=25&t=130

I am now using another method similar to this, but changing the original file, sometimes it works and sometimes it shows bsod if the additions are large (large API), and the size of the .dll grows a lot, meaning BSOD appears because the base address must be changed,

I managed to add some API's and it worked, but it worked Adding successfully is random, So maybe your method will be free of BSOD randomness,

should I put the name of the API that the original kernel32.dll is missing in .txt and then put the code of this API in the .cpp file? Why did you say the name of the functions in .txt, meaning many  and not the name of one function ?, do you mean that I can put several functions in a .cpp file or what? 

Please more explication 

Edited by windows2
Link to comment
Share on other sites

On 6/25/2022 at 10:07 AM, windows2 said:

@win32

https://forum.eclectic4un.me/viewtopic.php?f=25&t=130

I am now using another method similar to this, but changing the original file, sometimes it works and sometimes it shows bsod if the additions are large (large API), and the size of the .dll grows a lot, meaning BSOD appears because the base address must be changed,

I managed to add some API's and it worked, but it worked Adding successfully is random, well maybe your method will be free of BSOD randomness,

should I put the name of the API that the original kernel32.dll is missing in .txt and then put the code of this API in the .cpp file? Why did you say the name of the functions, meaning many  and not the name of one function ?, do you mean that I can put several functions in a .cpp file or what? 

Please more explication 

The original kernel32 would still exist, but it would be renamed to something else (i.e. kernel33). The new kernel32 still needs to export every function that the original kernel32 has, in addition to the new functions.

And yes you can write as many functions in a .c/.cpp file as possible, but keep organization techniques in mind.

Link to comment
Share on other sites

7 hours ago, win32 said:

The original kernel32 would still exist, but it would be renamed to something else (i.e. kernel33). The new kernel32 still needs to export every function that the original kernel32 has, in addition to the new functions.

And yes you can write as many functions in a .c/.cpp file as possible, but keep organization techniques in mind.

I think that I did not understand what you mean well because of my poor understanding of the English language,

but I did an experiment, where I came up with a API in the GetConsoleWindow.cpp file with the API code written in C++ 

Capture1.PNG.96f5340814ddf6941ccde6cfbb9f2b39.PNG

, and I wrote the name GetConsoleWindow in GetConsoleWindow.txt

Capture4.PNG.f025d5a8de045f751261a94a95013738.PNG

 

Capture2.PNG.205335a749a8dde5a0df1a2325be5b0d.PNG

then I ran scanexp and the result was like this, it was deleted the C++ code for GetConsoleWindow and change it with this comment

Capture3.PNG.91000e5fa77f11159b21cb571ff1a7ad.PNG

I think that my understanding of the work of this program is wrong :buehehe:,

how do you add functions with this ’?, you may need an in-depth explanation or make a video please , 

I discovered that the way I work now is not like this at all

Link to comment
Share on other sites

You typed "GetConsoleWindow..txt" when it is "GetConsoleWindow.txt", That will not work.

My intent for scanexp was to work for forwarding all the original exports to the original file when building a wrapper. To get all of them,
you would have to go into dependency walker, open the original file, and CTRL-A on the lower table of function names, then right-click to do as shown here:unknown.png
Paste into the text file.

Link to comment
Share on other sites

10 minutes ago, win32 said:

You typed "GetConsoleWindow..txt" when it is "GetConsoleWindow.txt", That will not work.

My intent for scanexp was to work for forwarding all the original exports to the original file when building a wrapper. To get all of them,
you would have to go into dependency walker, open the original file, and CTRL-A on the lower table of function names, then right-click to do as shown here:unknown.png
Paste into the text file.

Well, I think that I am affected by staying up late, and as I saw, I no longer see well, and as you see I made a terrible mistake "..txt" :lol:,

Tomorrow I will try and tell you

thanks

Link to comment
Share on other sites

  • 2 weeks later...

Windows NT4 Extended kernel

New Added API's :

 

KERNEL32.DLL:
Heap32ListFirst
Heap32ListNext
Heap32First
Heap32Next
Toolhelp32ReadProcessMemory
Process32FirstW
Process32First
Process32NextW
Process32Next
Thread32First
Thread32Next
Module32FirstW
Module32First
Module32NextW
Module32Next
CreateToolhelp32Snapshot

user32.dll:
GetMonitorInfoA
MonitorFromWindow

shell32.dll: 
SHGetFolderPathW

I managed to run the latest 7-zip version , work slowly but in the right way ;)

FXJnmrpWQAE8Fc4?format=jpg&name=large

 

Update for 15/07/22

New Added API's :

SETUPAPI.DLL :
SetupDiEnumDeviceInterfaces
pSetupMalloc
pSetupRealloc

ADVAPI32.DLL :
ConvertSidToStringSidW

OLE32.DLL :
CoWaitForMultipleHandles

USERENV.DLL :
ExpandEnvironmentStringsForUserW
ExpandEnvironmentStringsForUserA

user32.dll:

GetLayeredWindowAttributes
GetMonitorInfoW
MonitorFromPoint
MonitorFromRect
SetLayeredWindowAttributes

Edited by windows2
Link to comment
Share on other sites

10 hours ago, windows2 said:

Windows NT4 Extended kernel

New Added API's :

 

KERNEL32.DLL:
Heap32ListFirst
Heap32ListNext
Heap32First
Heap32Next
Toolhelp32ReadProcessMemory
Process32FirstW
Process32First
Process32NextW
Process32Next
Thread32First
Thread32Next
Module32FirstW
Module32First
Module32NextW
Module32Next
CreateToolhelp32Snapshot

user32.dll:
GetMonitorInfoA
MonitorFromWindow

shell32.dll: 
SHGetFolderPathW

I managed to run the latest 7-zip version , work slowly but in the right way ;)

Nice! I can't wait to try it once you're ready to release it if ever. However, I have a few questions. Once you have your kernelex finished, will will work with the Active Desktop Update shell?, and you said earlier that the way you did it is slightly different from how Win32 did it:

On 6/25/2022 at 7:07 AM, windows2 said:

I am now using another method similar to this

Could you briefly explain how you did it? Did it involve writing code? Otherwise, great to see the progress you're making on this.

Link to comment
Share on other sites

16 hours ago, testaccount66766 said:

Nice! I can't wait to try it once you're ready to release it if ever. However, I have a few questions. Once you have your kernelex finished, will will work with the Active Desktop Update shell?, and you said earlier that the way you did it is slightly different from how Win32 did it:

Could you briefly explain how you did it? Did it involve writing code? Otherwise, great to see the progress you're making on this.

Hello, I work with a program that is a little complicated and always exposed to BSOD that is difficult to fix  , and I cannot explain how to use it in writing :) ,

I decided at the beginning and I aspire to add as many missing DLL's functions as possible. I hope to continue my way, and I will do my best to add missing features and run as many modern programs as possible.

For Active Desktop Update shell maybe :) 

I discovered that this method is different from the @win32 method, and his method is easier if you are good at writing inline assembly code 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...