(http://i59.tinypic.com/143kps6.jpg)
CreateToolhelp32Snapshot v 1.2 (Updated version on 09/07/2014)v 1.2 (SnapShot_Guga3c2.zip - Works on WinNT and above)
* Added RTF (2.0) display
* Fixed support to Window NT (I hope :) )
* Fixed Module and thread listings
* Fixed process listings.
* Fixed SSE2 check - I hope :)
* Enabling report export in rtf format
v 1.2 (Xp version only to compare to the other one that also works on NT - SnapShot_Original3b2.zip)
________________________________________________________________________________________
Requirements:
RichEdit 2.0
Todo List:Create the heap listings.
Clean up the code
Finish further testings to compare the results of the original and mine version before implement the functions as a dll and make sure the functions are working on NT
Rebuild the SSE2 check to make it be for more general use. (See CPUID how they manage it. Or at intel references..They have a C code that can be ported to Assembly)
after creating the dll, add a progressbar on the executable demo just for fun
P.S.: The source code is embedded in the executable. To view or edit the source code you need to open the file in RosAsm.
________________________________________________________________________________________
________________________________________________________________________________________
CreateToolhelp32Snapshot v 1.1 (Updated version on 06/07/2014)
v 1.1 (SnapShot_Guga2c.zip)
* Fixed the last module thatwas not being displayed
* Implemented routines to check if the CPU contains SSE2
* Added faster memcopy and zeromemory routines to work with SSE2 (When the CPU allows it. Otherwise, it will use the default functions)
* Removed the calls to toolsnapshot win Apis from the demo to be tested on NT. Now it contains only mine versions of toolhelp
* Added the follwoing functions:
Module32First Module32FirstW
Module32Next Module32NextW
Thread32First Thread32Next
This is a test of the series of ToolHelp functions recreated from the original M$ Api.
So far, i suceeded to rebuild the following Apis
- CreateToolhelp32Snapshot
- Process32First
- Process32FirstW
- Process32Next
- Process32NextW
I´m pretty sure that on Process32Next there is a minor bug somewhere. I´m tracing it to compare to the results i found on the original APi to see if i can fix it.
Can someone test to see if the App works on WinnT ? (And on others windows versions too, such as win7, winvista, etc etc)
Note: This demo version was not designed to work on Win9x or below.
Btw:
SnapShot_Guga.zip = Mine version with the rebuilded Apis
SnapShot2_Original.zip = Same app using the M$ Apis
Note: This is a functional test, but the loading of modules and threads are disabled because i didn´t started to write the corresponding Apis. But...on
SnapShot2_Original you can see the modules and threads just uncommenting the following lines inside "BeginProcess" TITLE.
; List the modules and threads associated with this process
;call ListProcessModules D$hEdit, D@PROCESSENTRY32.th32ProcessIDDis
;call ListProcessThreads D$hEdit, D@PROCESSENTRY32.th32ProcessIDDis
DON´T UNCOMMENT THEM ON
MINE VERSION BECAUSE I DIDN´T BUILD THE NECESSARY APIS.
If you want to see the list of modules and threads uncoment those lines only on the
original version
I ran it on NT4 SP2, this is what happened (http://imgur.com/R2PQz8l)
Seems both exes import the actual Toolhelp functions. So I patched the export table of the _Guga.exe, and ran it again.
It started (exe was in taskmgr) but nothing happened, then about 4 seconds later it crashed with the bottom message. It's probably because NT4 before SP5 doesn't natively support SSE2 rather than any actual bugs (the illegal instruction is movdqu xmm1, qword ptr [esi+edx*8]).
It works on XP though
Tks adeyblue. I saw it.
This is because i forgot to remove the call to CreateToolhelp32Snapshot. I simply commented the functions that called them, but forgot to remove from this demo.
I´ll fix that and also see the problem of SSE2 instruction. I´ll have to add a routine to check for the SSE2 instructions and if it is not found, use the regular memcpy function.
I´m fixing that small problem of the absense of loading the last module (and therefore, the current we are using). It is a small mistake on the counting of the total loaded modules.
Once i fix i´ll post here with the corected functions to properly try to load on NT.
Many many tks for testing :):):)
I made a small function that checks for the presence of SSE2, but i´m not sure if NT have this Api
Proc SSE2_Available_init:
Uses ebx, esi, edi
C_call 'kernel32.IsProcessorFeaturePresent' &PF_XMMI64_INSTRUCTIONS_AVAILABLE
mov D$sse2_available eax
mov D$use_sse2_mathfcns eax
EndP
Does NT have thisapi inside ?
If not, i´ll try using the cpuid technique.
Btw...Dave, your routines of using cpuid to check for the processor also works to see if it contains SSE2 ?
because you are dealing with older machines...
you should first verify that the CPU supports CPUID
i'm not sure what the minimum processor is for NT, but i know Win95 would install on some older ones
but - the test is simple enough
you just test to see if you can toggle bit 21 of the EFLAGS register
pushfd
pop eax
mov ecx,200000h
mov edx,eax
xor eax,ecx
push eax
popfd
pushfd
pop eax
xor eax,edx
and eax,ecx
jz cpuid_not_supported
once you know CPUID is supported
execute CPUID with EAX = 0 to verify function 1 (at least) is supported
CPUID leaf 00000001h, EDX, bit 26 indicates SSE2 support
xor eax,eax
cpuid ;masm processor must be .586 or higher to assemble
or eax,eax
jz function_1_not_supported
cmp ah,5 ;verify not pre-B0 step family 5
jz function_1_not_supported
mov eax,1
cpuid
test edx,4000000h ;could also use BT EDX,26 -> sets CF if set
jnz sse2_supported
all CPU's that support SSE2 also support CPUID leaf 1 or higher
Tks Dave, i´ll give a try :t :t
One dumb question...In older machines that does not support cpuid...it also means that they don´t support SS/SSE2, right ?
all CPU's that support SSE2 also support CPUID function 1 or higher
i added that line at the end - probably after you saw the post :P
seems to work...
;***********************************************************************************************
IsSse2 PROC
;returns TRUE if SSE2 is supported
push ebx
pushfd
pop eax
mov ecx,200000h
mov edx,eax
xor eax,ecx
push eax
popfd
pushfd
pop eax
xor eax,edx
and eax,ecx
jz exit_proc
;once you know CPUID is supported
;execute CPUID with EAX = 0 to verify function 1 (at least) is supported
;CPUID leaf 00000001h, EDX, bit 26 indicates SSE2 support
xor eax,eax
cpuid ;masm processor must be .586 or higher to assemble
or eax,eax
jz exit_proc
cmp ah,5 ;verify not pre-B0 step family 5
jnz continue_test
xor eax,eax
jmp exit_proc
continue_test:
mov eax,1
cpuid
xchg eax,edx
shr eax,26
and eax,1
exit_proc:
pop ebx
ret
IsSse2 ENDP
;***********************************************************************************************
EDIT: couple minor improvements in flow
EDIT: also added PUSH/POP - easy to forget that CPUID alters EBX :P
here's one that's probably a bit more useful
it returns a value in EAX with individual bits set for MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, and SSE4.2
;***********************************************************************************************
GetSseLevel PROC
;EAX return bits:
;0 = MMX
;1 = SSE
;2 = SSE2
;3 = SSE3
;4 = SSSE3
;5 = SSE4.1
;6 = SSE4.2
pushfd
pop eax
mov ecx,200000h
mov edx,eax
xor eax,ecx
push eax
popfd
pushfd
pop eax
xor eax,edx
and eax,ecx
.if !ZERO?
push ebx
xor eax,eax
dw 0A20Fh ;cpuid instruction
.if eax
.if ah==5
xor eax,eax
.else
mov eax,1
dw 0A20Fh ;cpuid instruction
xor eax,eax
bt ecx,20 ;SSE4.2
rcl eax,1 ;into bit 6
bt ecx,19 ;SSE4.1
rcl eax,1 ;into bit 5
bt ecx,9 ;SSSE3
rcl eax,1 ;into bit 4
bt ecx,0 ;SSE3
rcl eax,1 ;into bit 3
bt edx,26 ;SSE2
rcl eax,1 ;into bit 2
bt edx,25 ;SSE
rcl eax,1 ;into bit 1
bt ecx,0 ;MMX
rcl eax,1 ;into bit 0
.endif
.endif
pop ebx
.endif
ret
GetSseLevel ENDP
Excellent code Dave :eusa_clap:
One question. Why you set the opcodes of cpuid, instead the instrucion itself ? Is it a problem on older versions of masm that does not assemble cpuid (as a mnemonic), or olders CPUs have different opcodes for cpuid ?
Btw: I fixed the minor bugs and now i´m rebuilding the Module32FirstW api. The next ones will be Module32Next and the Thread32First , Thread32Next series. Those will be enough to make the demo work properly to test on NT etc. Once i done them i´ll finish the rest of the whole set of toolhelp Apis and make a dll for it.
Another bug that is fixed from the original windows version is on Module32First Api, that returns ERROR_INVALID_PARAMETER instead the conversion of NTError code STATUS_INFO_LENGTH_MISMATCH.
Once i suceed to rebuild this whole toolhelp Api set, i´l try to add a couple of export functions that may be helpfull, such as a get SNAPSHOT structure to retrieve the Data directly from this structure that is loaded internally on the apis. And perhaps add more info related to the cpu, and possibly allowing dumping modules, processes, threads etc etc.
no - masm assembles the instruction fine
but, you must select .586 processor
by using DW, it will assemble with any selected 32-bit processor
unfortunately, masm32rt.inc has .486 in it - it would be better if it had .586 :P
AHn...i edited the previous comment while you were typing :greensml:
If you have any ideas of functions to add to this apis i´m rebuilding, let me know.
i guess i could have used PUSHCONTEXT/POPCONTEXT and .586 :P
;***********************************************************************************************
GetSseLevel PROC
;EAX return bits:
;0 = MMX
;1 = SSE
;2 = SSE2
;3 = SSE3
;4 = SSSE3
;5 = SSE4.1
;6 = SSE4.2
PUSHCONTEXT
.586
pushfd
pop eax
mov ecx,200000h
mov edx,eax
xor eax,ecx
push eax
popfd
pushfd
pop eax
xor eax,edx
and eax,ecx
.if !ZERO?
push ebx
xor eax,eax
cpuid
.if eax
.if ah==5
xor eax,eax
.else
mov eax,1
cpuid
xor eax,eax
bt ecx,20 ;SSE4.2
rcl eax,1 ;into bit 6
bt ecx,19 ;SSE4.1
rcl eax,1 ;into bit 5
bt ecx,9 ;SSSE3
rcl eax,1 ;into bit 4
bt ecx,0 ;SSE3
rcl eax,1 ;into bit 3
bt edx,26 ;SSE2
rcl eax,1 ;into bit 2
bt edx,25 ;SSE
rcl eax,1 ;into bit 1
bt ecx,0 ;MMX
rcl eax,1 ;into bit 0
.endif
.endif
pop ebx
.endif
ret
POPCONTEXT
GetSseLevel ENDP
;***********************************************************************************************
OK, guys
I updated the file. Can someone test it on NT ?
adeyblue can you try now to see if it works ?
Many tks.
It crashes in the same way, on what looks like exactly the same instruction though it's now at 0x406f4e. My CPU supports SSE2 (Intel Pentium 2020M), I think it's something within NT that hates it, so it'd require a version check as well as a CPUID check.
Anyway, I hacked your exe to always use non-SSE path and the dialog appears. Here's the text it shows (http://pastebin.com/75kdhZj6). Looks good, the PID's correspond with what taskmgr shows anyway.
For reference, IsProcessorFeaturePresent exists on NT4, but not on either NT 3 version if that matters. I've got some VMs of those but I'm currently fighting Adobe Premiere Pro so it might be a few days before I can test them.
Indeed, a windows version check would also be required then.
But....at least i´m glad to know the function is actually working on WINNT :biggrin: :biggrin: :biggrin: :biggrin:
I´try to finishing this app to build the proper dll to everyone can use it on their own apps :greenclp:
it might be better to use LoadLibrary/GetProcAddress/FreeLibrary
the reason is.....
on some versions of windows CE, the system architect may select which functions are to be supported
so - checking the version may not always get you the info you need
i use this method on a few functions
if the OS doesn't support the function, i don't call it :biggrin:
also....
there were a few problems in the masm32 package with Process32First/Next and Module32First/Next
possibly with Thread32First/Next, Heap32First/Next, and Heap32ListFirst/Next
some of the history...
http://www.masmforum.com/board/index.php?topic=18294.0 (http://www.masmforum.com/board/index.php?topic=18294.0)
http://www.masmforum.com/board/index.php?topic=18850.15 (http://www.masmforum.com/board/index.php?topic=18850.15)
http://www.masmforum.com/board/index.php?topic=18900.0 (http://www.masmforum.com/board/index.php?topic=18900.0)
Using loadlibrary... Why ? WinCE does not have the ntdll apis ??
I´m not sure i understood this. You mean that if i build a dll containing mine version of this Apis, WinCE will choose the ones existent inside kernel just because the Api names are the same ?
The functions im making are not the ones inside kernel. I rebuilded them to they also work in NT (That don´t have those Apis) and fixed some bugs existent inside the ones from Kernel32.dll.
For example, mine version of CreateToolhelp32Snapshot is this:
Proc CreateToolhelp32Snapshot::
Arguments @dwFlags, @th32ProcessID
Local @RawDebugInfo, @RawModule, @RawProcess, @CurProcID, @SectionHandle
Uses esi, ecx, ebx
If D@th32ProcessID = 0
call 'KERNEL32.GetCurrentProcessId'
Else
mov eax D@th32ProcessID
End_If
mov D@CurProcID eax
lea ecx D@RawDebugInfo | mov D$ecx 0
lea ebx D@RawModule | mov D$ebx 0
lea eax D@RawProcess | mov D$eax 0
call ThpCreateRawSnap D@dwFlags, D@CurProcID, eax, ebx, ecx
If eax <> &STATUS_SUCCESS
call BaseSetLastNTError eax
or eax &INVALID_HANDLE_VALUE | ExitP
End_If
lea eax D@SectionHandle | mov D$eax 0
call ThpAllocateSnapshotSection eax, D@dwFlags, D@CurProcID, D@RawProcess, D@RawModule, D@RawDebugInfo
If eax <> &STATUS_SUCCESS
call BaseSetLastNTError eax
or eax &INVALID_HANDLE_VALUE | ExitP
End_If
call ThpProcessToSnap D@dwFlags, D@CurProcID, D@SectionHandle, D@RawProcess, D@RawModule, D@RawDebugInfo
If eax <> &STATUS_SUCCESS
mov esi eax
call 'kernel32.CloseHandle' D@SectionHandle
call BaseSetLastNTError esi
or eax &INVALID_HANDLE_VALUE | ExitP
End_If
mov eax D@SectionHandle
EndP
(...)
Proc ThpAllocateSnapshotSection:
Arguments @SnapSection, @dwFlags, @th32ProcessID, @RawProcess, @RawModule, @RawDebugInfo
Local @IsRawProcess, @IsModule, @IsHeapList, @RegionSize, @SnapshotBase, @SnapShotSize, @ThreadCount,
@ProcessCount, @ModuleCount, @HeapListCount, @Status
Uses ebx, esi, edi, ecx, edx
mov D@ModuleCount 0
mov D@HeapListCount 0
mov D@ProcessCount 0
mov D@ThreadCount 0
mov D@IsRawProcess &FALSE
mov D@IsModule &FALSE
mov D@IsHeapList &FALSE
mov D@SnapShotSize Size_Of_SNAPSHOTSTATE
; calculate the required snapshot size
.Test_If D@dwFlags &TH32CS_SNAPPROCESS__&TH32CS_SNAPTHREAD
mov esi D@RawProcess; current position of the structure
Do
inc D@ProcessCount ; the total amount of the process used on the system
mov ecx D$esi+SYSTEM_PROCESS_INFORMATION.NumberOfThreadsDis | add D@ThreadCount ecx ; how many threads we have so far ?
; the next entry is the current address plus the next offset
add esi D$esi+SYSTEM_PROCESS_INFORMATION.NextEntryOffsetDis
; See if the next entry we have something there. If there is no next entry, end the loop
Loop_Until D$esi+SYSTEM_PROCESS_INFORMATION.NextEntryOffsetDis = 0
inc D@ProcessCount ; and finally, include the previous process
mov ecx D$esi+SYSTEM_PROCESS_INFORMATION.NumberOfThreadsDis
add D@ThreadCount ecx
Test_If D@dwFlags &TH32CS_SNAPPROCESS
mov esi D@ProcessCount | imul esi Size_Of_PROCESSENTRY32W | add esi Size_Of_SNAPSHOTSTATE | mov D@SnapShotSize esi
Test_End
Test_If D@dwFlags &TH32CS_SNAPTHREAD
mov eax D@ThreadCount | imul eax Size_Of_THREADENTRY32 | add D@SnapShotSize eax
Test_End
mov D@IsRawProcess &TRUE
.Test_End
Test_If D@dwFlags &TH32CS_SNAPMODULE
mov eax D@RawModule | mov eax D$eax+RTL_DEBUG_INFORMATION.ModulesDis | mov eax D$eax+RTL_PROCESS_MODULES.NumberOfModulesDis | mov D@ModuleCount eax
imul eax Size_of_MODULEENTRY32W | add D@SnapShotSize eax
mov D@IsModule &TRUE
Test_End
Test_If D@dwFlags &TH32CS_SNAPHEAPLIST
mov eax D@RawDebugInfo | mov eax D$eax+RTL_DEBUG_INFORMATION.HeapsDis | mov eax D$eax+RTL_PROCESS_HEAPS.NumberOfHeapsDis | mov D@HeapListCount eax
imul eax Size_Of_HEAPLIST32 | add D@SnapShotSize eax
mov D@IsHeapList &TRUE
Test_End
; Create a security object if needed
Test_If D@dwFlags &TH32CS_INHERIT
mov D$SECURITY_ATTRIBUTES.nLength Size_Of_SECURITY_ATTRIBUTES
mov D$SECURITY_ATTRIBUTES.lpSecurityDescriptor 0
mov D$SECURITY_ATTRIBUTES.bInheritHandle &TRUE
mov eax SECURITY_ATTRIBUTES
Test_Else
xor eax eax
Test_End
; create a pagefile section to contain the snapshot
call BaseFormatObjectAttributes OBJECT_ATTRIBUTES, eax, &NULL
move D$SectionSize.LowPart D@SnapShotSize
mov D$SectionSize.HiPart 0
call 'ntdll.NtCreateSection' D@SnapSection, &STANDARD_RIGHTS_REQUIRED__&SECTION_MAP_READ__&SECTION_MAP_WRITE__&SECTION_QUERY,
eax, SectionSize, &PAGE_READWRITE, &SEC_COMMIT, &NULL
On eax <> &STATUS_SUCCESS, ExitP
; that´s weird. Here D@SnapSection points to what seems to be a structure. The 6ths member seems to points to the stack of the functon hat called the dl.
mov D$SectionOffset.LowPart 0
mov D$SectionOffset.HiPart 0
mov D$ViewSize 0
mov D$ViewSize+4 0
mov esi D@SnapSection
lea eax D@SnapshotBase | mov D@SnapshotBase 0
call 'ntdll.NtMapViewOfSection' D$esi, 0-1, eax, 0, 0, SectionOffset, ViewSize, &SECTION_INHERIT_VIEWSHARE, &NULL, &PAGE_READWRITE
mov D@Status eax
...If eax <> &STATUS_SUCCESS
; free all memory if failure
call 'kernel32.CloseHandle' D$esi
If D@IsRawProcess = &TRUE
mov edi D@RawProcess
mov D@RegionSize 0
lea eax D@RegionSize
call 'ntdll.NtFreeVirtualMemory' 0-1, edi, eax, &MEM_RELEASE
mov D$edi 0
End_If
If_Or D@IsModule = &TRUE, D@IsRawProcess = &TRUE
mov edi D@RawModule
call 'ntdll.RtlDestroyQueryDebugBuffer' edi
mov D$edi 0
End_If
If D@IsHeapList = &TRUE
mov edi D@RawDebugInfo
call 'ntdll.RtlDestroyQueryDebugBuffer' edi
mov D$edi 0
End_If
...Else
; return resources
mov eax D@SnapshotBase
move D$eax+SNAPSHOTSTATE.HeapListCountDis D@HeapListCount
move D$eax+SNAPSHOTSTATE.ProcessCountDis D@ProcessCount
move D$eax+SNAPSHOTSTATE.ModuleCountDis D@ModuleCount
move D$eax+SNAPSHOTSTATE.ThreadCountDis D@ThreadCount
call 'ntdll.NtUnmapViewOfSection' 0-1, D@SnapshotBase
...End_If
mov eax D@Status
EndP
If you could not spam the entire forum userbase with notifications about this, that would be great.
Quote from: Tedd on July 07, 2014, 09:59:17 PM
If you could not spam the entire forum userbase with notifications about this, that would be great.
So I was not the only one then...
I don't get notifications. What do they show in this case?
Jochen - we all received an e-mail announcing this thread, basically :dazzled:
Gustavo - sorry - i misunderstood the problem
deleted
I got one as well. ( have turned that option off as we don't want anyone sending notifications to all members.
So what. Gustavo made a little flaw, but he meant well. No big deal.
Gunther
Oops...sorry about that. I checked the option thinking it was simply put a warning message on the topic saying it have a newer version when i uploaded one.
Didn´t knew it will send emails to everyone.
Tks steve, the option is disable now :)
ok - i have a couple questions for Bob (adeyblue)
if your install of NT4 does not support SSE2, but your CPU does...
1) does your CPU report SSE2 with the GetSseLevel procedure i posted earlier ? (see reply #8 or 12)
i.e., the OS may disable the feature bit
2) are you able to use MMX or SSE(1) instructions ?
haha, my names not Bob. That's just an old habit of what I type in VMs. My name's Adrian.
Anyway:
1) NT4 returns 0x1f in eax so everything up to SSSE3. On Win7 I get 0x7f, which is news to me because I didn't know I had SSE4.2 but appparently so.
2) MMX works, at least movq and emms do. SSE, at least xorps, don't (illegal instruction).
There's apparently a driver in NT4 SP5 which enables at least some SSE functionality, but my SP5 exe is on a different machine so I can't install and test it.
ok, Bob Adrian :biggrin:
no need for SP5 test - you told me exactly what i wanted to know
that is: if IsProcessorFeaturePresent is not exported in kernel32, we can assume there is no SSE support
probably a good assumption, at least
out of curiosity, i wrote this little test app
posting results in here doesn't do a lot of good, because both the OS and the CPU need to be ID'ed
and - the variations of the 2 would make for messy comparison
but, it makes it easy to see which features appear on your own machine
XP MCE2005 SP3, Prescott w/htt
PF_FLOATING_POINT_PRECISION_ERRATA: 0
PF_FLOATING_POINT_EMULATED: 0
PF_COMPARE_EXCHANGE_DOUBLE: 1
PF_MMX_INSTRUCTIONS_AVAILABLE: 1
PF_PPC_MOVEMEM_64BIT_OK: 0
PF_ALPHA_BYTE_INSTRUCTIONS: 0
PF_XMMI_INSTRUCTIONS_AVAILABLE: 1
PF_3DNOW_INSTRUCTIONS_AVAILABLE: 0
PF_RDTSC_INSTRUCTION_AVAILABLE: 1
PF_PAE_ENABLED: 1
PF_XMMI64_INSTRUCTIONS_AVAILABLE: 1
PF_SSE_DAZ_MODE_AVAILABLE: 0
PF_NX_ENABLED: 1
PF_SSE3_INSTRUCTIONS_AVAILABLE: 0
PF_COMPARE_EXCHANGE128: 0
PF_COMPARE64_EXCHANGE128: 0
PF_CHANNELS_ENABLED: 0
PF_XSAVE_ENABLED: 0
PF_ARM_VFP_32_REGISTERS_AVAILABLE: 0
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: 0
PF_SECOND_LEVEL_ADDRESS_TRANSLATION: 0
PF_VIRT_FIRMWARE_ENABLED: 0
PF_RDWRFSGSBASE_AVAILABLE: 0
PF_FASTFAIL_AVAILABLE: 0
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: 0
PF_ARM_64BIT_LOADSTORE_ATOMIC: 0
PF_ARM_EXTERNAL_CACHE_AVAILABLE: 0
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE: 0
PF_RDRAND_INSTRUCTION_AVAILABLE: 0
On the NT4 VM. CPU is reported as "Intel family 6 model 10 stepping 9" whatever that corresponds to:
PF_FLOATING_POINT_PRECISION_ERRATA: 0
PF_FLOATING_POINT_EMULATED: 1
PF_COMPARE_EXCHANGE_DOUBLE: 1
PF_MMX_INSTRUCTIONS_AVAILABLE: 1
PF_PPC_MOVEMEM_64BIT_OK: 0
PF_ALPHA_BYTE_INSTRUCTIONS: 0
PF_XMMI_INSTRUCTIONS_AVAILABLE: 0
PF_3DNOW_INSTRUCTIONS_AVAILABLE: 0
PF_RDTSC_INSTRUCTION_AVAILABLE: 0
PF_PAE_ENABLED: 0
PF_XMMI64_INSTRUCTIONS_AVAILABLE: 0
PF_SSE_DAZ_MODE_AVAILABLE: 0
PF_NX_ENABLED: 0
PF_SSE3_INSTRUCTIONS_AVAILABLE: 0
PF_COMPARE_EXCHANGE128: 0
PF_COMPARE64_EXCHANGE128: 0
PF_CHANNELS_ENABLED: 0
PF_XSAVE_ENABLED: 0
PF_ARM_VFP_32_REGISTERS_AVAILABLE: 0
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: 0
PF_SECOND_LEVEL_ADDRESS_TRANSLATION: 0
PF_VIRT_FIRMWARE_ENABLED: 0
PF_RDWRFSGSBASE_AVAILABLE: 0
PF_FASTFAIL_AVAILABLE: 0
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: 0
PF_ARM_64BIT_LOADSTORE_ATOMIC: 0
PF_ARM_EXTERNAL_CACHE_AVAILABLE: 0
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE: 0
PF_RDRAND_INSTRUCTION_AVAILABLE: 0
On Win7 SP1 x64. IvyBridge/2020M:
PF_FLOATING_POINT_PRECISION_ERRATA: 0
PF_FLOATING_POINT_EMULATED: 0
PF_COMPARE_EXCHANGE_DOUBLE: 1
PF_MMX_INSTRUCTIONS_AVAILABLE: 1
PF_PPC_MOVEMEM_64BIT_OK: 0
PF_ALPHA_BYTE_INSTRUCTIONS: 0
PF_XMMI_INSTRUCTIONS_AVAILABLE: 1
PF_3DNOW_INSTRUCTIONS_AVAILABLE: 0
PF_RDTSC_INSTRUCTION_AVAILABLE: 1
PF_PAE_ENABLED: 1
PF_XMMI64_INSTRUCTIONS_AVAILABLE: 1
PF_SSE_DAZ_MODE_AVAILABLE: 0
PF_NX_ENABLED: 1
PF_SSE3_INSTRUCTIONS_AVAILABLE: 1
PF_COMPARE_EXCHANGE128: 1
PF_COMPARE64_EXCHANGE128: 0
PF_CHANNELS_ENABLED: 0
PF_XSAVE_ENABLED: 1
PF_ARM_VFP_32_REGISTERS_AVAILABLE: 0
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: 0
PF_SECOND_LEVEL_ADDRESS_TRANSLATION: 0
PF_VIRT_FIRMWARE_ENABLED: 0
PF_RDWRFSGSBASE_AVAILABLE: 0
PF_FASTFAIL_AVAILABLE: 0
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: 0
PF_ARM_64BIT_LOADSTORE_ATOMIC: 0
PF_ARM_EXTERNAL_CACHE_AVAILABLE: 0
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE: 0
PF_RDRAND_INSTRUCTION_AVAILABLE: 0
I got the NT3.1 VM up after a fight but getting anything modern running on it is a nightmare. No msvcrt.dll, madness!
PF_FLOATING_POINT_EMULATED: 1
i'm a little surprised to see that one :redface:
the MSVCRT issue could be overcome by replacing the str$ macro with a routine to convert to ASCII decimal
QuoteIntel family 6 model 10 stepping 9
it's a Pentium III Xeon
Ok guys
I updated it
Adrian (adeyblue), can you test on NT please ? I hope it is working now. I´m using IsProcessorFeaturePresent Api to check for the presence of WinNT. If this Api does not exists, then it will use the non SSE2 version.
It also will return a non SSE2 if IsProcessorFeaturePresent detects you don´t have it enable (accordying to msdn the flag is PF_XMMI64_INSTRUCTIONS_AVAILABLE)
I rebuilded the routine to check as simply this:
[CPU_Extension: D$ 0]
[CPU_EXTENSION_MMX 00_1]
[CPU_EXTENSION_SSE 00_10]
[CPU_EXTENSION_SSE2 00_100]
[CPU_EXTENSION_SSE3 00_1000]
[CPU_EXTENSION_SSSE3 00_10000]
[CPU_EXTENSION_SSE41 00_100000]
[CPU_EXTENSION_SSE42 00_1000000]
Proc SSECheck:
Uses ebx, esi, edi
Local @hpfIsProcessorFeaturePresent
call 'KERNEL32.LoadLibraryA' {B$ 'kernel32.dll', 0}
call 'KERNEL32.GetProcAddress' eax, {B$ 'IsProcessorFeaturePresent', 0} | mov D@hpfIsProcessorFeaturePresent eax
.If eax <> 0
C_call D@hpfIsProcessorFeaturePresent &PF_XMMI64_INSTRUCTIONS_AVAILABLE
If eax = 0
mov D$CPU_Extension 0
Else
mov D$CPU_Extension CPU_EXTENSION_SSE2
End_If
.Else
mov D$CPU_Extension 0
.End_If
EndP
Later i´ll try to see better what Dave did and why it is not working on yours.
Btw...Dave , as far i remember there is a C function made by intel that can check this. (I´m uploading here for you a zip file that checks SSE4.2. Maybe you can find the other c code in intel reference manuals)
Damn M$, the heapxx functions are giving me on my nerves. Only one function missing (Heap32Next) and again, i see bugs (defined as such in their own Source since win NT...Which btw...is not fixed in XP yet and most probably nor fixed in win7 or above). The computing of the heap segments are made by guess, even thinking that they are just formed as an array of structures mapped from ntdll.dll.
I don´t know how M$ development team made such a mess on their own code. Don´t they communicate each other ? I mean, the guy that created the toolhelp functinos didn´t talked to the ones that made the RTL memory mapping/creation functions, such RtlCreateQueryDebugBuffer ???
I´ll port that stuff, but will definitely need to build other functions to reestructure the SNAPSHOT structure to it be properly mapped so the pointers and flags for the toolhelp can be correctly defined. I personally don´t care much what taskmanager says, because underneath it uses apis that "guesses" the pointers from memory, instead simply computing them.
Hi Dave,
Results posted due to the P-MMX not reporting MMX available.
And on which processor did the RDTSC instruction start? P-Pro?
P-MMX
PF_FLOATING_POINT_PRECISION_ERRATA: 0
PF_FLOATING_POINT_EMULATED: 0
PF_COMPARE_EXCHANGE_DOUBLE: 0
PF_MMX_INSTRUCTIONS_AVAILABLE: 0
PF_PPC_MOVEMEM_64BIT_OK: 0
PF_ALPHA_BYTE_INSTRUCTIONS: 0
PF_XMMI_INSTRUCTIONS_AVAILABLE: 0
PF_3DNOW_INSTRUCTIONS_AVAILABLE: 0
PF_RDTSC_INSTRUCTION_AVAILABLE: 0
PF_PAE_ENABLED: 0
PF_XMMI64_INSTRUCTIONS_AVAILABLE: 0
PF_SSE_DAZ_MODE_AVAILABLE: 0
PF_NX_ENABLED: 0
PF_SSE3_INSTRUCTIONS_AVAILABLE: 0
PF_COMPARE_EXCHANGE128: 0
PF_COMPARE64_EXCHANGE128: 0
PF_CHANNELS_ENABLED: 0
PF_XSAVE_ENABLED: 0
PF_ARM_VFP_32_REGISTERS_AVAILABLE: 0
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: 0
PF_SECOND_LEVEL_ADDRESS_TRANSLATION: 0
PF_VIRT_FIRMWARE_ENABLED: 0
PF_RDWRFSGSBASE_AVAILABLE: 0
PF_FASTFAIL_AVAILABLE: 0
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: 0
PF_ARM_64BIT_LOADSTORE_ATOMIC: 0
PF_ARM_EXTERNAL_CACHE_AVAILABLE: 0
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE: 0
PF_RDRAND_INSTRUCTION_AVAILABLE: 0
Press any key to continue ...
P-III
PF_FLOATING_POINT_PRECISION_ERRATA: 0
PF_FLOATING_POINT_EMULATED: 0
PF_COMPARE_EXCHANGE_DOUBLE: 1
PF_MMX_INSTRUCTIONS_AVAILABLE: 1
PF_PPC_MOVEMEM_64BIT_OK: 0
PF_ALPHA_BYTE_INSTRUCTIONS: 0
PF_XMMI_INSTRUCTIONS_AVAILABLE: 1
PF_3DNOW_INSTRUCTIONS_AVAILABLE: 0
PF_RDTSC_INSTRUCTION_AVAILABLE: 1
PF_PAE_ENABLED: 0
PF_XMMI64_INSTRUCTIONS_AVAILABLE: 0
PF_SSE_DAZ_MODE_AVAILABLE: 0
PF_NX_ENABLED: 0
PF_SSE3_INSTRUCTIONS_AVAILABLE: 0
PF_COMPARE_EXCHANGE128: 0
PF_COMPARE64_EXCHANGE128: 0
PF_CHANNELS_ENABLED: 0
PF_XSAVE_ENABLED: 0
PF_ARM_VFP_32_REGISTERS_AVAILABLE: 0
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: 0
PF_SECOND_LEVEL_ADDRESS_TRANSLATION: 0
PF_VIRT_FIRMWARE_ENABLED: 0
PF_RDWRFSGSBASE_AVAILABLE: 0
PF_FASTFAIL_AVAILABLE: 0
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: 0
PF_ARM_64BIT_LOADSTORE_ATOMIC: 0
PF_ARM_EXTERNAL_CACHE_AVAILABLE: 0
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE: 0
PF_RDRAND_INSTRUCTION_AVAILABLE: 0
Press any key to continue ...
Regards,
Steve N.
IIRC, for the Intel processors RDTSC started with the original Pentium.
it's sort of a mess - that's why it does little good to collect data in the forum
you have to consider the OS version when the IsProcessFeaturePresent function began supporting each value
so - a feature might well be available and in use - but not reported for the OS/SP level you are using
a good approach might be to consider the OS and SP
then stop listing features at a certain spot in the list :P
the last 4 or 5 only showed up in windows 8, for example
it really makes the function somewhat useless, because you'd need some kind of "reporting matrix" to validate the results
if a bit is set, you know it's supported - otherwise, you know less than you did before - lol
it might be useful for determining if AVX is supported, though
hindsight, of course
but, it would be nicer if they had returned -1 for unsupported index values :t
Hi,
Quote from: MichaelW on July 09, 2014, 10:44:04 PM
IIRC, for the Intel processors RDTSC started with the original Pentium.
Thanks, that's what I thought. So the reported results were
wrong.
Quote from: dedndave on July 09, 2014, 10:53:24 PM
it's sort of a mess - that's why it does little good to collect data in the forum
Oh. Should have believed you then, and not posted.
Quote
you have to consider the OS version when the IsProcessFeaturePresent function began supporting each value
so - a feature might well be available and in use - but not reported for the OS/SP level you are using
[...]
it really makes the function somewhat useless, because you'd need some kind of "reporting matrix" to validate the results
if a bit is set, you know it's supported - otherwise, you know less than you did before -
Well did Windows 98 predate the Pentium? In which case the
results may make sense. (No, not really.)
Thanks,
Steve N.
Quote from: FORTRANS on July 09, 2014, 11:46:07 PM
Well did Windows 98 predate the Pentium? In which case the
results may make sense. (No, not really.)
no :biggrin:
but, consider the timeline....
at some point, the ms programmers decided it was pertinent for this function to report it
and so, they added the PF_RDTSC_INSTRUCTION_AVAILABLE index
that obviously came after windows 98 and the pentium
it would make a lot more sense if it had returned -1 :t
Quote from: guga on July 09, 2014, 01:27:08 PM
Adrian (adeyblue), can you test on NT please ? I hope it is working now.
Sorry :-( RichEdit10AnsiWndProc doesn't exist in riched20.dll. All that dll exports on NT4 is
_DllMain@12
CreateTextServices
IID_IRichEditOle
IID_IRichEditOleCallback
IID_ITextHost
IID_ITextHost2
IID_ITextServices
I replaced it the dll with the version from Win 2000 and it works, did notice one bug though. For the [System Process] it ends up enumeratng the modules of the current process.
=====================================================
PROCESS NAME: [System Process]
=====================================================
_____________________________________________________
Warning !!!! The following error ocurred:
Error Title: 'Api OpenProcess error'
Error Message: 'The parameter is incorrect.'
_____________________________________________________
_____________________________________________________
Process ID = 0 (0x00000000) <---------------- System process
Thread Count = 1
Parent Process ID = 0 (0x00000000)
Priority Base = 0
Priority Class = Error. See message above
_____________________________________________________
MODULE NAME: Gugac2.exe
_____________________________________________________
Executable = C:\share\Gugac2.exe
_____________________________________________________
Process ID = 1584 (0x00000630) <---------------- Current process
Ref Count (g) = Not meanfull (0x0000FFFF)
Ref Count (p) = Not meanfull (0x0000FFFF)
Base Address = 0x00400000
Base Size = 40960
_____________________________________________________
MODULE NAME: ntdll.dll
_____________________________________________________
Executable = C:\WINDOWS\system32\ntdll.dll
_____________________________________________________
Process ID = 1584 (0x00000630) <---------------- Current process
Ref Count (g) = Not meanfull (0x0000FFFF)
Ref Count (p) = Not meanfull (0x0000FFFF)
Base Address = 0x7C900000
Base Size = 716800
_____________________________________________________
It's probably because of CreateToolhelp32Snapshot(TH32CS_SNAPMODULE) thinking the process id of 0 means the current process.
Quote from: adrian
Sorry :-( RichEdit10AnsiWndProc doesn't exist in riched20.dll. All that dll exports on NT4 is
_DllMain@12
CreateTextServices
IID_IRichEditOle
IID_IRichEditOleCallback
IID_ITextHost
IID_ITextHost2
IID_ITextServices
I replaced it the dll with the version from Win 2000 and it works, did notice one bug though. For the [System Process] it ends up enumeratng the modules of the current process.
wahoooooo :bgrin: :bgrin: :bgrin:
Then the problem is on the usage of richedit on the rtf demo functions and not the rebuilded toolhelp apis functions :) :):):) (I´ll review the rtf fix once i succeed to fix the Heap32Next problem i´m currently doing.
Anyway, it is good to know the rebuilded Apis are fully working on NT now, the same way as the original version.
About enumerating the current system. Excellent, this happens here too. It seems to be an error on M$ example i ported and not the rebuilded Api functions.
I ported the functions examples as in here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686701%28v=vs.85%29.aspx
If i compiled the C function in VS it will give me these results too (The same ones as in both gui versions):
=====================================================
PROCESS NAME: [System Process]
-------------------------------------------------------
WARNING: OpenProcess failed with error 87 (The parameter is incorrect)
Process ID = 0x00000000
Thread count = 8
Parent process ID = 0x00000000
Priority base = 0
MODULE NAME: Snapshot.exe
Executable = D:\RosAsm\RosAsm\ToolHelpLib\Debug\Snapshot.exe
Process ID = 0x0000B250
Ref count (g) = 0xFFFF
Ref count (p) = 0xFFFF
Base address = 0x00400000
Base size = 32768
MODULE NAME: ntdll.dll
Executable = C:\WINDOWS\system32\ntdll.dll
Process ID = 0x0000B250
Ref count (g) = 0xFFFF
Ref count (p) = 0xFFFF
Base address = 0x7C900000
Base size = 729088
Can you check this source for me ? I mean, it does as it expects, or there is actually a bug in the original Api that i also reproduced it after porting it ? I would like to be sure either it is a bug on M$ example or in the Apis themselves (If it is a bug on the api, i can try fixing them, but... it seems more like an error on the C example).
I´m amazed the rebuilded Apis worked as expected on Win NT. It means that they are being correctly ported to assembly in order for me to do a proper dll containing them. Once i finish Heap32Next i´ll try to make a function similar to Toolhelp32ReadProcessMemory (Which is already rebuilded, btw) but, instead reading the memory from a specific address it will export the whole SNAPSHOT structure to the user analyse it. Or create a Toolhelp32ReadProcessMemoryEx function where it returns the total amount of bytes necessary for the buffer, in case of failures or also under user choice.
For instance, Toolhelp32ReadProcessMemoryEx can use lpBaseAddress as a flag to determine the amount of allocated memory. So if you set lpBaseAddress = 0, it returns the amount of bytes to you use either in Toolhelp32ReadProcessMemory or in Toolhelp32ReadProcessMemoryEx
Quote from: guga
About enumerating the current system. Excellent, this happens here too. It seems to be an error on M$ example i ported and not the rebuilded Api functions.
So it is. I didn't run the one using the MS functions when I tried it on XP so I didn't notice that it did it as well. So yeah, it appears that it's another bug to chalk up to MSDN. Because I had nothing better to do, I went and looked to see if CreateToolhelp32Snapshot(MODULES, 0) meant the current process on Win95, which is most likely when that example was written, and it did. So it's that sample that's buggy and your replacements are perfectly fine.
Don't know if you really care about NT 3.1 but I checked ntdll.dll's exports (http://jsbin.com/vezezada/1) against what your exe imports and unfortunately none of the RTL_DEBUG_INFORMATION related functions exist.
Indeed, NT 3.1 does not seems to have the following apis:
RtlCreateQueryDebugBuffer
RtlDestroyQueryDebugBuffer
RtlQueryProcessDebugInformation
I took a fast look onto mine ntdll (XP) for this functions, and it seems it can also be ported since it uses others apis that do exist on NT 3.1. So, i´ll try porting them too :)
Many tks for the listing :)
Btw: since some of those functions uses TEB, i´ll probably need to add a routine that checks for which WindowZZZ version it is currently being used. ::)
In general i take the information about TEb from Nirsoft (http://www.nirsoft.net/kernel_struct/vista/TEB.html), or UNdocumented Internals (http://undocumented.ntinternals.net) but...i just found a website from Michal Trojnara which seems to be far more complete and accurated accodying to the sources i have of winNT, Win2000 and WinXP educacional. His links are: Link 01 (http://msdn.mirt.net/win7rtm_x64.html), Link 02 (http://msdn.mirt.net), Link 03 (http://msdn.moonsols.com)