PDA

Click to See Complete Forum and Search --> : Hava a look--Get the CPU name by ASM code!


ENet
Jul 22nd, 2005, 04:07 AM
Option Explicit

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private x As Long

Function GetCpuName() As String

Dim MachineCode(0 To 34) As Byte
Dim VarAddr As Long
Dim FunctAddr As Long
Dim EAX As Long
Dim CPUName(1 To 12) As Byte

'设置机器代码
MachineCode(0) = &H55 'push ebp
MachineCode(1) = &H8B 'move ebp,esp
MachineCode(2) = &HEC
MachineCode(3) = &H57 'push edi
MachineCode(4) = &H52 'push edx
MachineCode(5) = &H51 'push ecx
MachineCode(6) = &H53 'push ebx
MachineCode(7) = &H8B 'move eax,dword ptr [ebp+8]
MachineCode(8) = &H45
MachineCode(9) = &H8
MachineCode(10) = &HF 'cpuid
MachineCode(11) = &HA2
MachineCode(12) = &H8B 'mov edi,dword ptr [ebp+12]
MachineCode(13) = &H7D
MachineCode(14) = &HC
MachineCode(15) = &H89 'move dword ptr [edi],ebx
MachineCode(16) = &H1F
MachineCode(17) = &H8B 'mov edi,dword ptr [ebp+16]
MachineCode(18) = &H7D
MachineCode(19) = &H10
MachineCode(20) = &H89 'move dword ptr [edi],ecx
MachineCode(21) = &HF
MachineCode(22) = &H8B 'mov edi,dword ptr [ebp+20]
MachineCode(23) = &H7D
MachineCode(24) = &H14
MachineCode(25) = &H89 'move dword ptr [edi],edx
MachineCode(26) = &H17
MachineCode(27) = &H58 'pop ebx
MachineCode(28) = &H59 'pop ecx
MachineCode(29) = &H5A 'pop edx
MachineCode(30) = &H55 'pop edi
MachineCode(31) = &HC9
MachineCode(32) = &HC2
MachineCode(33) = &H10
MachineCode(34) = &H0
EAX = 0
VarAddr = VarPtr(MachineCode(0)) '得到机器代码的地址
FunctAddr = GetAddress(AddressOf Dummy) '得到子程序 Dummy的地址
'把机器代码拷贝到能够被调用的地方
CopyMemory ByVal FunctAddr, ByVal VarAddr, 35 '机器代码的长度为35比特

Call CallWindowProc(FunctAddr, EAX, VarPtr(CPUName(1)), VarPtr(CPUName(9)), VarPtr(CPUName(5)))
GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeName
End Function

Private Function GetAddress(Address As Long) As Long
GetAddress = Address
End Function

Private Sub Dummy()
x = 0: x = 1: x = 2
x = 3: x = 4: x = 5
x = 6: x = 7: x = 8
x = 9: x = 10: x = 0
x = 1: x = 2: x = 3
x = 4: x = 5: x = 6
x = 7: x = 8: x = 9
x = 10
End Sub

Pino
Jul 22nd, 2005, 04:45 AM
I'm guesing this is not a question? I have moved to codebank!

penagate
Jul 22nd, 2005, 06:15 AM
Assembly bit was good, but VB needed a bit of work ;)

Public Function CPUname__ASM() As String
Static asmCPUIDProc(34) As Byte
Dim chCPUName(11) As Byte

asmCPUIDProc(0) = &H55 ' push ebp
asmCPUIDProc(1) = &H8B ' move ebp,esp
asmCPUIDProc(2) = &HEC
asmCPUIDProc(3) = &H57 ' push edi
asmCPUIDProc(4) = &H52 ' push edx
asmCPUIDProc(5) = &H51 ' push ecx
asmCPUIDProc(6) = &H53 ' push ebx
asmCPUIDProc(7) = &H8B ' move eax, dword ptr [ebp+8]
asmCPUIDProc(8) = &H45
asmCPUIDProc(9) = &H8
asmCPUIDProc(10) = &HF ' cpuid
asmCPUIDProc(11) = &HA2
asmCPUIDProc(12) = &H8B ' mov edi, dword ptr [ebp+12]
asmCPUIDProc(13) = &H7D
asmCPUIDProc(14) = &HC
asmCPUIDProc(15) = &H89 ' move dword ptr [edi],ebx
asmCPUIDProc(16) = &H1F
asmCPUIDProc(17) = &H8B ' mov edi, dword ptr [ebp+16]
asmCPUIDProc(18) = &H7D
asmCPUIDProc(19) = &H10
asmCPUIDProc(20) = &H89 ' move dword ptr [edi],ecx
asmCPUIDProc(21) = &HF
asmCPUIDProc(22) = &H8B ' mov edi,dword ptr [ebp+20]
asmCPUIDProc(23) = &H7D
asmCPUIDProc(24) = &H14
asmCPUIDProc(25) = &H89 ' move dword ptr [edi],edx
asmCPUIDProc(26) = &H17
asmCPUIDProc(27) = &H58 ' pop ebx
asmCPUIDProc(28) = &H59 ' pop ecx
asmCPUIDProc(29) = &H5A ' pop edx
asmCPUIDProc(30) = &H55 ' pop edi
asmCPUIDProc(31) = &HC9
asmCPUIDProc(32) = &HC2
asmCPUIDProc(33) = &H10
asmCPUIDProc(34) = &H0

CallWindowProc VarPtr(asmCPUIDProc(0)), _
0, _
VarPtr(chCPUName(0)), _
VarPtr(chCPUName(8)), _
VarPtr(chCPUName(4))

CPUname__ASM = StrConv(chCPUName, vbUnicode)
End Function

Hack
Jul 22nd, 2005, 10:31 AM
Since this was more ASM than VB, I felt it belonged in Other.

wossname
Sep 9th, 2005, 05:37 AM
Hack, thats silly, it enables VB6 programmers to use fast ASM code in their apps, it belongs in VB codebank.

This is excellent.

wossname
Sep 14th, 2005, 04:30 AM
Assembly bit was good, but VB needed a bit of work ;)


Penagate, if I wanted to write my own ASM and use this technique, how would I know which bytes to put into the array?

Would I just write the program in MASM (for example), compile it and then use a hex editor to copy and paste the compiled bytes into the array?

Would I have to leave out certain bits of the compiled code?

Or will all this become clear once I've started to learn ASM? I've just found
http://www.amazon.com/exec/obidos/tg/detail/-/0130910139/qid=1126688008/sr=2-2/ref=pd_bbs_b_2_2/102-0159135-4499321?v=glance&s=books
on amazon. Thinking of ordering it.

penagate
Sep 14th, 2005, 04:59 AM
Penagate, if I wanted to write my own ASM and use this technique, how would I know which bytes to put into the array?

Would I just write the program in MASM (for example), compile it and then use a hex editor to copy and paste the compiled bytes into the array?
That's basically it yes. I'd advise you use a program such as FASM (http://www.flatassembler.net), which only compiles the opcodes you type in, without any overhead of program structure. Perfect for this situation. As you said, once it's compiled you need to open the file (.BIN) in a hex editor and paste the bytes into your array initialiser.

Bear in mind, how you actually code the routine is language and call convention specific. Inline ASM in VC++ is very easy as the compiler allows you to access variables and arguments in the C++ code and simply compiles them as required. In VB, and I suppose C#, you need to know exactly where the variables are and how they are passed on the stack, so you can access them.

I have no real experience doing this using stdcall (the call convention used in VB) but I know in cdecl (C/C++ calling convention) the arguments are passed right to left on the stack. So to access them you can do this
int myfunc(int arg1, int arg2)
{
_asm {
mov eax, dword ptr [esp - 4]
mov ebx, dword ptr [esp - 8]
}
}
esp is the stack pointer register and you subtract 4 and 8 from that respectively to get the two 4-byte int variables we passed to the function.

I don't know what call convention C# uses (I presume that's what you'd be doing it in) so you'd have to read up on its finer details to get your precompiled ASM working. And be completely aware of the state of variables, etc. in the procedure, at the point at which you execute the ASM code.

wossname
Sep 14th, 2005, 08:31 AM
Cool, thanks :)

yrwyddfa
Sep 15th, 2005, 07:34 AM
http://hackbase.com/hacker/program/2005080513018.html

Unless you wrote the source, you should indicate from where it came from.
It's a matter or politeness.

(and the code produces a stack pointer error in the VB IDE, too - it only works correctly when compiled to native code)

penagate
Sep 15th, 2005, 07:38 AM
That is the silliest code. You need to call GetCpuName() to retrieve the CPU name yet every time you call it you copy the ASM code into another procedure and call that by using an API (why they did not just make that the function I do not know). It is so wasteful.

yrwyddfa
Sep 15th, 2005, 07:45 AM
There's all sorts of variants of this function all over the web. Some are good, some are bad, but nearly all of them produce a stack pointer error when used with p-code, or in the IDE (because VB doesn't know how to correctly exit the function)

I think - but I'm not sure - that you're gonna need the techniques from Matt Curland's Advanced Visual Basic 6 book.

Look for the function delegator stuff to properly manage the stack so that VB can call arbitrary pointers to functions.

penagate
Sep 15th, 2005, 07:48 AM
If you want to copy ASM code over a dummy VB function like they are trying to do here, you could at least do it properly. Give it a proper signature and call it from VB instead of an API for goodness sake. And you need a "ret" instruction in there as well.