Builder içerisinde kullanıcağımız APIler:
BeginUpdateResource,UpdateResource,EndResource
Stub içerisinde kullanıcağımız APIler :
FindResource,SizeofResouce,LoadResource,LockResource
API,İşletim sistemlerinin size açtığı fonksiyonlardır.Bunların prototipleri bilinir.yukarıdaki fonksiyonların prototipler şu şekildedir:
HANDLE WINAPI BeginUpdateResource(
_In_ LPCTSTR pFileName,
_In_ BOOL bDeleteExistingResources
);
BeginUpdateResource WINAPI si bize,UpdateResource tarafından Kaynak ekleme,silme,
yer değiştirme işlemleri yapabileceğimiz bir handle döner.
peki handle nedir? prosesin handle tablosuna index olarak geçirilir.handle sayesinde işletim
sistemi kaynağa ilişkin olayları takip edebilir.
pFileName,üzerinde Resource işlemleri yapıcağınız dosya bu parametreye geçirilir.
bDeleteExistingResources,pFileName ait olan kaynakların silinip/silinmeyeceğini buradan
bildirebilirsiniz.eğer bu parametreye true verilirse,diğer resourcelar silinir.örneğin bu değer
true olursa VERSION INFO ve MANIFEST gibi bilgiler exe file da silinir.
BOOL WINAPI UpdateResource(
_In_ HANDLE hUpdate,
_In_ LPCTSTR lpType,
_In_ LPCTSTR lpName,
_In_ WORD wLanguage,
_In_opt_ LPVOID lpData,
_In_ DWORD cbData
);
UpdateResource,PE dosyası içerisindeki kaynağa ekler,siler veya değişiklik uygular.biz burada
belirli bir ham data gömme işlemi yapıcaz.
Kısaca parametrelerini tanıyacak olursak.
hUpdate,BeginUpdateResource tarafından dönülen handle bu parametreye geçirilir.
lpType,Resource tipi bu parametreyle belirtir.MAKEINTRESOURCE(ID) makrosuyla C dilinde ilgili
tip geçirilebilir.Resource türler belirlidir.biz bu parametreye RT_RCDATA geçiricez,
RAW Data olarak bilinir,türkçesi ham veridir.
lpName,Resource'unuzun ismini keyfi olarak seçip bu parametreye geçiririz.örneğin "Kernsteinist".
wLanguage,üzerinde işlem yapıcağımız kaynağın Language Identifierını belirtir.
meraklılarına şöyle açıklayabilirim,Language Identifier ülke ya da bölge için tanımlanmış
uluslararası standart bir sayıdır.Her bir dil 16-bitlik Unique ID(kendisine has eşsiz)sahiptir.
+-------------------------+-------------------------+
| SubLanguage ID | Primary Lang ID |
+-------------------------+-------------------------+
15 10 9 0 bit
yukarıdaki gibi tanımlanır.
PrimaryLanguage dili belirtirken SubLanguage ise ülke veya bölgeyi belirtir.Bir dilin
birden fazla ülkede konuşulmasından dolayı bu şekilde tanımlanmıştır.
lpData,Kaynağa eklenecek veriyi byte dizi olarak bu parametreye geçiriyoruz.
cbData,Kaynağa eklenecek verinin boyutunu belirtiyoruz.
BOOL WINAPI EndUpdateResource(
_In_ HANDLE hUpdate,
_In_ BOOL fDiscard
);
hUpdate,BeginUpdateResource'un döndüğü handle bu parametreye geçiriyoruz.fDiscard,Yaptıklarımızın dosyaya yazılıp/yazılmayacağını belirtir,bu parametre false girilirse
belirtiğimiz işlemler yapılır ve Resource(RT_RCDATA) belirttiğimiz datayla exe dosyasına gömülmüş olur.true değerinde yaptıklarımız exe file uygulanmaz.
YUKARIDA ANLATILANLAR BUİLDER İÇERİSİNDE UYGULAYACAKLARIMIZ.
HRSRC WINAPI FindResource(
_In_opt_ HMODULE hModule,
_In_ LPCTSTR lpName,
_In_ LPCTSTR lpType
);
Bu
fonksiyon stub içerisinde yer alacak.belirttiğimiz lpName(Resource'un
ismi),lpType(Resource'un Türü) ile kaynağın yerini belirten bir handle
döner.eğer 0 dönerse aradığımız resource bulunamadı.DWORD WINAPI SizeofResource(
_In_opt_ HMODULE hModule,
_In_ HRSRC hResInfo
);
Tahmin edebileceğiniz gibi Resource boyunun bilgisini buradan elde ederiz.bize Resource'un boyutunu döner.
hResInfo,bulunan kaynağı işaret eden handle buraya geçirilir.FindResource tarafından dönülen handle değeridir.
HGLOBAL WINAPI LoadResource(
_In_opt_ HMODULE hModule,
_In_ HRSRC hResInfo
);
parametreleri SizeofResource ile aynı.Belirtilen kaynağın memorydeki ilk bytenı işaret eden adresi elde etmek için kullanabileceğimiz bir handle bize getirir.(HGLOBAL)
LPVOID WINAPI LockResource(
_In_ HGLOBAL hResData
);
LoadResource bize getirdiği handle değerini buraya geçiririz,eğer kaynak mevcutsa bize Resource'un ilk bytenı işaret eden bir pointer döner.kaynak mevcut değilse NULL değer döner.
Bu arada Parametreleri tanımlayan ifadelere macar notasyonu denir(Hungarian Notation)
Bu notasyona ilişkin bir kaç örnek vereyim:
LPCTSTR = Long Pointer To a Constant TCHAR STRing,yani const char*
WORD = 16 bit,2 byte olarak bilinir.
LPVOID = Long Pointer VOID,yani Void*
Bu kadar bilgiden sonra C# dilinde bu işin gerçekleştirilmesi şöyledir :
BUİLDER CODE :
STUB CODE :
class Program
{
//GetLastError fonksiyonunu kullanıcaksanız SetLastError=True yapmalısınız.
//Marshal.GetLastWin32Error() ile API üzerinde meydana gelmiş hataya ilişkin kodu alabilirsiniz.
//Created By Kernsteinist
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr BeginUpdateResource(string pFileName,bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
static byte[] Convert_To_Byte(string to_be_added)
{
byte[] to_byte = new byte[to_be_added.Length];
for (int i = 0; i < to_be_added.Length; i++)
{
char c = to_be_added[i];
to_byte[i] = (byte)c;
}
return to_byte;
}
static void Main(string[] args)
{
Console.WriteLine("Enter anything value :");
string to_be_added = Console.ReadLine();
File.Copy("STUB.EXE", "Kernsteinist.EXE",true);
IntPtr hUpdate = BeginUpdateResource("Kernsteinist.exe", false);
bool error = UpdateResource(hUpdate,"RT_RCDATA", "Kern", 0, Convert_To_Byte(to_be_added),(uint)to_be_added.Length);
if (!error)
{
Console.WriteLine("Error...");
Console.WriteLine(Marshal.GetLastWin32Error());
EndUpdateResource(hUpdate, true);
}
else
{
EndUpdateResource(hUpdate, false);
Console.WriteLine("Succesful...");
} } }
unsafe class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr FindResource(int hModule, string lpName, string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int SizeofResource(int hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(int hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource(IntPtr hResData);
static void Main(string[] args)
{
IntPtr HRSRC = FindResource(0, "Kern", "RT_RCDATA");
int size = SizeofResource(0, HRSRC);
IntPtr hResData = LoadResource(0, HRSRC);
IntPtr s = LockResource(hResData);
byte* b = (byte*)(s); //Resource'un ilk bytenın adresi.
Console.WriteLine("......");
for (int i = 0; i < size; i++)
{
byte data1 = (byte)*(b+i);
Console.Write(data1.ToString()+" ");
}
Console.WriteLine("......");
for (int i = 0; i < size; i++)
{
byte data1 = (byte)*(b + i);
Console.Write((char)data1);
}
}
}
Unsafe,Keywordu pointer kullanmamıza izin verilmesi için kullanmamız gereken keyword.
Projectinizin üzerine gelip sağ tıklayıp properties,daha sonra sol tarafta build tıklayın ve "Allow
Unsafe Code" seçin.
EOF
Hiç yorum yok:
Yorum Gönder