
Chciałbym napisać aplikację, która generować będzie PID klucza systemu przy pomocy biblioteki pidgenx.dll (jest w każdym systemie windows powyżej XP[choć w xp chyba również]).
W Internecie jest wiele przykładów kodów, ale żaden nie jest w C++

Tak więc podam może kilka przykładów, jakie znalazłem w różnych językach, może uda nam się coś z tego wyczytać:
RealBasic (to jest cały, działający program):
- Kod: Zaznacz cały
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//This project/code is provided by Daz from mydigitallife.info, it's open source and may be used by anyone.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StatusPage.DeleteAllRows
If System.IsFunctionAvailable("PidGenX","pidgenx.dll") Then
StatPoint.Text = "Status: Processing, please wait..."
Me.Sleep(1000)
#pragma DisableBackgroundTasks True
Soft Declare Function PidGenX Lib "pidgenx.dll" (WindowsKey As WString, PkeyPath As WString, MPCID As WString, UnknownUsage As Integer, GeneratedProductID As Ptr, OldDigitalProductID As Ptr, DigitalProductID As Ptr) As Integer
//////////////////////////////////////////////////////////////
Dim GenPID As New MemoryBlock(100)
GenPID.Byte(0) = 50
//
Dim OldPID As New MemoryBlock(164)
OldPID.Byte(0) = 164
//
Dim CoreData As New MemoryBlock(1272)
CoreData.Byte(0) = 248
CoreData.Byte(1) = 4
//////////////////////////////////////////////////////////////
Dim RetID As Integer = PidGenX(Serial, ConfigPath, "XXXXX", 0, GenPID, OldPID, CoreData) //The MPC ID can be anything, this is just an example so I have kept it basic.
//////////////////////////////////////////////////////////////
If RetID = 0 Then
//////////
Dim PID As String = CleanupString(GenPID.WString(0)) //PID
Dim EPID As String = CleanupString(CoreData.WString(8)) //Extended PID
Dim AID As String = CleanupString(CoreData.WString(136)) //Activation ID
Dim WEDID As String = CleanupString(CoreData.WString(280)) //Edition
Dim SubType As String = CleanupString(CoreData.WString(888)) //Subtype
Dim LType As String = CleanupString(CoreData.WString(1016)) //License type
Dim CID As String = CleanupString(CoreData.WString(1144)) //License channel
//////////
StatusPage.AddRow("Key status: Valid")
If PID <> "" Then StatusPage.AddRow("PID: "+PID)
If EPID <> "" Then StatusPage.AddRow("Extended PID: "+EPID)
If AID <> "" Then StatusPage.AddRow("Activation ID: "+AID)
If WEDID <> "" Then StatusPage.AddRow("Edition: "+WEDID)
If SubType <> "" Then StatusPage.AddRow("Subtype: "+SubType)
If LType <> "" Then StatusPage.AddRow("License type: "+LType)
If CID <> "" Then StatusPage.AddRow("License channel: "+CID)
If EPID <> "" Then StatusPage.AddRow("Crypto ID: "+Mid(EPID,9,3))
ElseIf RetID = -2147024894 Then
StatusPage.AddRow("Error: pkeyconfig.xrm-ms is missing")
ElseIf RetID = -2147024809 Then
StatusPage.AddRow("Error: Invalid arguments")
//ElseIf RetID = -1979645695 Then
//StatusPage.AddRow("Key status: Invalid")
Else
StatusPage.AddRow("Key status: Invalid") //Just incase we will say invalid for all other errors
End If
#pragma DisableBackgroundTasks False
StatPoint.Text = "Status: Waiting..."
Else
StatusPage.AddRow("Unsupported OS")
End If
C++ (ale w .net

- Kod: Zaznacz cały
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr LoadLibrary(string fileName);
[DllImport("kernel32", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("pidgenx.dll", EntryPoint = "PidGenX", CharSet = CharSet.Auto)]
static extern int PidGenX(string ProductKey, string PkeyPath, string MSPID, int UnknownUsage, IntPtr ProductID, IntPtr DigitalProductID, IntPtr DigitalProductID4);
private string CheckProductKey(string ProductKey)
{
string dllPath = temp + "\\pidgenx.dll"; //temp is the folder path that has the dll and config file
IntPtr dllHandle = LoadLibrary(dllPath);
.
.
.
string PKeyPath = temp + "\\pkeyconfig.xrm-ms";
.
.
.
Marshal.FreeHGlobal(PID);
Marshal.FreeHGlobal(DPID);
Marshal.FreeHGlobal(DPID4);
bool clear = true;
while(clear) //Must be run thrice in order to dereference the pointer
clear = FreeLibrary(dllHandle);
return result;
}
Tutaj jest VB.net (ale podobno nie do konca działający):
- Kod: Zaznacz cały
Imports System.Runtime.InteropServices
Public Class Form1
Declare Auto Function PidGenX Lib "C:\pidgen_v_32.dll" _
(ByVal one As String, _
ByVal two As String, _
ByVal three As String, _
ByVal four As IntPtr, _
ByVal five As IntPtr, _
ByVal six As IntPtr, _
ByVal seven As IntPtr) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Dim keystring As String = "BH626-XT3FK-MJKJH-6GQT2-QXQMF"
Dim pkeypath As String = "C:\pkeyconfig.xrm-ms"
Dim num As String = "55041"
Dim unk1 As IntPtr = 0
Dim genPID As IntPtr = Marshal.AllocHGlobal(100)
Marshal.WriteByte(genPID, 0, &H32)
Marshal.WriteByte(genPID, 1, &H0)
Marshal.WriteByte(genPID, 2, &H0)
Marshal.WriteByte(genPID, 3, &H0)
Dim cleargenPID As Integer = 0
For cleargenPID = 4 To 99
Marshal.WriteByte(genPID, cleargenPID, &H0)
Next cleargenPID
Dim oldPID As IntPtr = Marshal.AllocHGlobal(164)
Marshal.WriteByte(oldPID, 0, &HA4)
Marshal.WriteByte(oldPID, 1, &H0)
Marshal.WriteByte(oldPID, 2, &H0)
Marshal.WriteByte(oldPID, 3, &H0)
Dim clearoldPID As Integer = 0
For clearoldPID = 4 To 163
Marshal.WriteByte(oldPID, clearoldPID, &H0)
Next clearoldPID
Dim DPID4 As IntPtr = Marshal.AllocHGlobal(1272)
Marshal.WriteByte(DPID4, 0, &HF8)
Marshal.WriteByte(DPID4, 1, &H4)
Marshal.WriteByte(DPID4, 2, &H0)
Marshal.WriteByte(DPID4, 3, &H0)
Dim clearDPID4 As Integer = 0
For clearDPID4 = 4 To 1271
Marshal.WriteByte(DPID4, clearDPID4, &H0)
Next clearDPID4
Dim query As Integer = PidGenX(keystring, pkeypath, num, unk1, genPID, oldPID, DPID4)
Dim message As String = "Return code: " + query.ToString + vbNewLine
message += vbNewLine
If (query = 0) Then message += "Valid key: " + keystring
If (query = -2147024894) Then message += "pkeyconfig.xrm-ms is missing"
If (query = -2147024809) Then message += "generic arguments incorrect"
If (query = -1979645695) Then message += "Invalid key: " + keystring
message += vbNewLine
message += vbNewLine
Dim readgpid As Integer = 0
Dim curbyte As Integer = 0
Dim tpid As String = ""
For readgpid = 0 To 99
curbyte = Marshal.ReadByte(genPID, readgpid)
If ((curbyte > 31) And (curbyte <127> 31) And (currbyte <127> 31) And (currentbyte < 127)) Then
transferdpid += Chr(currentbyte)
Else
transferdpid += "."
End If
Next readdpid
Dim vistapid As String = transferdpid
message += "Arg 5, Generated PID:" + vbNewLine + ">>" + gpid + "<<" + vbNewLine
message += vbNewLine
message += "Arg 6, Old PID:" + vbNewLine + ">>" + xppid + "<<" + vbNewLine
message += vbNewLine
message += "Arg 7, DPID4:" + vbNewLine + ">>" + vistapid + "<<" + vbNewLine
message += vbNewLine
TextBox1.Clear()
TextBox1.AppendText(message)
Marshal.FreeHGlobal(oldPID)
Marshal.FreeHGlobal(DPID4)
Marshal.FreeHGlobal(genPID)
End Sub
End Class
A tutaj jest mój kod, któryz oczywiście nie działa, no bo jak:
- Kod: Zaznacz cały
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
#pragma argsused
#include <windows.h>
#include <stdio.h>
#include <string.h>
using namespace std;
// DLL function signature:
typedef int (*importFunction)(UnicodeString WindowsKey, UnicodeString PkeyPath, UnicodeString MSPID, int *UnknownUsage, int *ProductID, int *DigitalProductID, int *DigitalProductID4);
int main(int argc, char **argv)
{
UnicodeString Key = "Tutaj wpisuje 29znakowy klucz (wraz z myslnikami), ale na razie nic tu nie bedzie, bo byloby to nieco nielegalne";
importFunction GeneratePID;
int result;
// Te "struct'y" powinny chyba być po wykonaniu funkcji, a tutaj powinno znajdowac sie cos typu BYTE (ale nie wiem)
struct DigitalProductId {
unsigned int uiSize;
BYTE bUnknown1[4];
char szProductId[28];
char szEditionId[16];
BYTE bUnknown2[112];
};
struct DigitalProductId4 {
unsigned int uiSize;
BYTE bUnknown1[4];
WCHAR szAdvancedPid[64];
WCHAR szActivationId[72];
WCHAR szEditionType[256];
BYTE bUnknown2[96];
WCHAR szEditionId[64];
WCHAR szKeyType[64];
WCHAR szEULA[64];
};
// Load DLL file
HINSTANCE hinstLib = LoadLibrary(TEXT("pidgenx.dll"));
if (hinstLib == NULL) {
printf("ERROR: unable to load DLL\n");
return 1;
}
// Get function pointer
GeneratePID = (importFunction)GetProcAddress(hinstLib, "PidGenX");
if (GeneratePID == NULL) {
printf("ERROR: unable to find DLL function\n");
FreeLibrary(hinstLib);
return 1;
}
// Call function.
result = GeneratePID(Key, "pkeyconfig.xrm-ms", "XXXX", 0, NULL, DigitalProductId, DigitalProductId4);
// Unload DLL file
FreeLibrary(hinstLib);
// Display result
return 0;
system("pause");
}
//---------------------------------------------------------------------------
Wytłumaczę jeszcze jedno - DigitalProductID to ciąg bajtów, który składa się z 164 bajtów, gdzie pierwszy to 164 (czyli rozmiar ciągu), a pozostałe elementy analogicznie:
DigitalProductID4 jest długi na 1272 bajty, zaczynać się musi dwoma bajtami: 248 i 4 ProductID ma długość 100 i zaczyna się bajtem o wartości dziesiętnej 50.
Domyślam się, że mam to zrobić przez Serializację, jednak nie wiem jak taki zabieg przeprowadzić no i nie wiem jaki jest odpowiednik IntPtr w C++ - dopiero zaczynam zabawę w programowanie

No więc, wiem że to jest to skomplikowane i mam nadzieję, że razem jakoś damy temu radę.
Dziękuję z góry za jakiekolwiek wskazówki i proszę o nie pisanie postów w stylu "poczytaj, google.com, zobacz w podręczniku, itd"
EDIT:
A i zapomniałem dodac, że funkcja PidGenX zwraca wartości w formie argumentów, czyli: 4 ostatnie argumenty, chociaż właściwie 3, bo "UnknownUsage" jest mi niepotrzebny, mają być przekazywane do funkcji, zmieniane przez nią, co ma powodować, że zmienne w moim programie przyjmą określoną wartość (czyli chyba coś ze wskaźnikami.