码迷,mamicode.com
首页 > 其他好文 > 详细

ASM 取CPU序列号 / CPUID

时间:2015-08-02 20:06:11      阅读:447      评论:0      收藏:0      [点我收藏+]

标签:

获取CPU序列号我知道大概有两种方式一种为ASM另一种为WMI

如果要好点的话肯定是首选汇编了、没什么好解释的哇 不过今天

我们只在C#、C++、E三种语言上内嵌汇编实现获取CPUID的办法

首先我们先看看下面各种语言代码运行后的效果图、

技术分享

上面是C#嵌入汇编运行后获取到的CPUID 我们在看看易语言上的

技术分享

上面是E语言嵌入汇编后运行的结果 两者输出的值是相同、

可以证明嵌入的汇编运行上没有问题、

技术分享

上面是C++嵌入汇编后运行的结果 两者输出的值是相同、

#include "stdafx.h"

#include <stdio.h>

int* GetGPUID()
{
	__asm
	{
		mov eax,00h
		xor edx,edx
		cpuid
		mov dword ptr [ebp-4],edx
		mov dword ptr [ebp-8],eax

		mov eax,01h
		xor ecx,ecx
		xor edx,edx
		cpuid
		mov dword ptr [ebp-12],edx
		mov dword ptr [ebp-16],eax

		mov         eax,dword ptr [ebp-4]  
		mov         dword ptr [ebp-20],eax  
		mov         eax,dword ptr [ebp-8]  
		mov         dword ptr [ebp-24],eax  
		mov         eax,dword ptr [ebp-12]  
		mov         dword ptr [ebp-28],eax  
		mov         eax,dword ptr [ebp-16]  
		mov         dword ptr [ebp-32],eax  

		lea         eax, dword ptr[ebp-20]  
		pop         edi
		pop         esi
		pop         ebx
		mov         esp,ebp
		pop         ebp
		ret
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int* ptr = GetGPUID();
	int s1 = *ptr++;
	int s2 = *ptr++;
	int s3 = *ptr++;
	int s4 = *ptr;
	printf("%X%X%X%X", s1, s2, s3, s4);
	getchar();
	return 0;
}

上面是在C++中内嵌的汇编代码部分、功能与C#与E语言的相同

.版本 2
.支持库 eAPI

.子程序 __启动窗口_创建完毕
.局部变量 ptr, 整数型
.局部变量 s1, 整数型
.局部变量 s2, 整数型
.局部变量 s3, 整数型
.局部变量 s4, 整数型

ptr = CallWindowProc ({ 85, 139, 236, 129, 236, 192, 0, 0, 0, 83, 86, 87, 141, 189, 64, 255, 255, 255, 185, 48, 0, 0, 0, 184, 204, 204, 204, 204, 243, 171, 184, 0, 0, 0, 0, 51, 210, 15, 162, 137, 85, 252, 137, 69, 248, 184, 1, 0, 0, 0, 51, 201, 51, 210, 15, 162, 137, 85, 244, 137, 69, 240, 139, 69, 252, 137, 69, 236, 139, 69, 248, 137, 69, 232, 139, 69, 244, 137, 69, 228, 139, 69, 240, 137, 69, 224, 141, 69, 236, 95, 94, 91, 139, 229, 93, 195 }, #NULL, #NULL, #NULL, #NULL)

s1 = 指针到整数 (ptr)
s2 = 指针到整数 (ptr + 4)
s3 = 指针到整数 (ptr + 8)
s4 = 指针到整数 (ptr + 12)

信息框 (格式化文本 (“%X%X%X%X”, s1, s2, s3, s4), #信息图标, , )

上面是E语言内嵌汇编的调用的代码、不过我倒是很建议大家下载打包的源代码

里面包含C++、E语言、C#三种不同的代码 我不是很喜欢Java你们可以看不起我、

不否认我是一名C#屌丝程序员、虽然我一直很菜菜啦、但是我相当快乐、咔咔

上面的汇编是在x86上进行的、所以你需要在C#项目属性中把 目标平台 / 开发环境

修改为x86不然等会你把代码全部搞定运行不了、才搞笑的心慌 你说是不是?

技术分享

现在我们开始编写代码,我们需要把常量以及需要的API全部声明出来

不然等会怎么用、嘻嘻 的吧

    static partial class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool VirtualProtect(byte[] lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr CallWindowProc(byte[] lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);

        private const int NULL = 0;
        private const int PAGE_EXECUTE_READWRITE = 64;
    }

现在我们必须要把嵌入到C#里面的汇编以机器码的形式写出来

    static partial class Program
    {
        private static readonly byte[] buf_asm = { 85, 139, 236, 129, 236, 192, 0, 0, 0, 83, 86, 87, 141, 189, 64, 255, 255, 255, 185, 48, 0, 0, 0, 184, 204, 204, 204, 204, 243, 171, 184, 0, 0, 0, 0, 51, 210, 15, 162, 137, 85, 252, 137, 69, 248, 184, 1, 0, 0, 0, 51, 201, 51, 210, 15, 162, 137, 85, 244, 137, 69, 240, 139, 69, 252, 137, 69, 236, 139, 69, 248, 137, 69, 232, 139, 69, 244, 137, 69, 228, 139, 69, 240, 137, 69, 224, 141, 69, 236, 95, 94, 91, 139, 229, 93, 195 };
    }

现在我们开始进入正规了、编写修改内存保护的代码 否则等会

一调用就GameOver上次我在写另一片文章中专门提到过这个问

题,如果有需要可以看看 http://blog.csdn.net/u012395622/article/details/46801475

    static partial class Program
    {
        private static void VirtualProtect(byte[] address)
        {
            uint lpflOldProtect;
            VirtualProtect(address, address.Length, PAGE_EXECUTE_READWRITE, out lpflOldProtect);
        }
    }

 好的、热血澎湃的时刻到了 准备好编写下面的代码 快快快 呵呵

    static partial class Program
    {
        private static string GetCPUID()
        {
            VirtualProtect(buf_asm);
            IntPtr ptr = CallWindowProc(buf_asm, NULL, NULL, NULL, NULL);

            int s1 = Marshal.ReadInt32(ptr);
            int s2 = Marshal.ReadInt32(ptr, 4);
            int s3 = Marshal.ReadInt32(ptr, 8);
            int s4 = Marshal.ReadInt32(ptr, 12);

            return s1.ToString("X") + s2.ToString("X") + s3.ToString("X") + s4.ToString("X");
        }
    }

我的废话一下,因为在汇编中返回的是一个整型数组的指针、而

整形数组只有4个值,所以你会看到上面我一直在调用Marshal.ReadInt32

当然你也可以使用C#中的原生指针、那感觉很酸爽 哈哈、

然后在把s1-s4的所有值转换成“%X十六进制格式文本”链接在一起

返回给调用方,OK解决问题、上次我是使用委托调用汇编本次换为

CallWindowProc去呼叫函数地址、两个差不多 我只是不想在写委托了、

    static partial class Program
    {
        [STAThread]
        static void Main()
        {
            Console.WriteLine(GetCPUID());
            Console.ReadKey(false);
        }
    }

上面是在C#滴Main函数中调用GetCPUID函数的部分,本次的意义

并不大、反正逼格已经完美 再也不担心妈妈说我不懂编程了、呵呵

源代码:http://pan.baidu.com/s/1ntBtQUd // 含C++、E语言、C#三种语言的源代码、

C#的源代码添加到你项目中时记得先把开发环境切换为x86不然运行不了 别怪我、

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

ASM 取CPU序列号 / CPUID

标签:

原文地址:http://blog.csdn.net/u012395622/article/details/47209359

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!