Prosty przykład, jak skompilować i wywołać dynamiczną metodę C#, wykorzystując wbudowany mechanizm kompilacji w .NET.
C#
Antidebugging w aplikacjach Android
Dzisiaj analizowałem sobie jedną starszą aplikację i natknąłem się na ciekawy kod, sprawdzający kilka rzeczy, których autorzy sobie nie życzą (to nie jest koncert życzeń), marnie zakamuflowanych pod fałszywymi nazwami 😀
Sprawdzane są m.in.
- Czy urządzenie było zrootowanie i czy dostępne są narzędzia takie jak np. komenda su.
- Czy podpięty jest debugger
- Czy zainstalowane są ehem wrogie aplikacje
Kod mówi więcej niż słowa, dlatego spójrzcie sami, może komuś ta wiedza się kiedyś przyda, z zastrzeżeniem, że to starsza aplikacja i kilka rzeczy mogło się już zmienić.
using System;
using System.Collections.Generic;
using System.IO;
using Android.App;
using Android.Content.PM;
using Android.OS;
using Xamarin.Forms;
namespace Abc
{
// Token: 0x02000010 RID: 16
public class CalendarService : ICalendarService
{
// Token: 0x06000044 RID: 68 RVA: 0x000080A5 File Offset: 0x000062A5
public bool IsDateCorrect()
{
return this.IsDayCorrect() || this.IsProperUtcFormat() || this.IsMonthCorrect() || this.IsCurrentMonth() || this.IsItReallyCurrentYearAlready();
}
// Token: 0x06000045 RID: 69 RVA: 0x000080D0 File Offset: 0x000062D0
public bool IsDayCorrect()
{
using (List<string>.Enumerator enumerator = new List<string>
{
"/system/app/Superuser.apk",
"/sbin/su",
"/system/bin/su",
"/system/xbin/su",
"/data/local/xbin/su",
"/data/local/bin/su",
"/system/sd/xbin/su",
"/system/bin/failsafe/su",
"/data/local/su",
"/su/bin/su"
}.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (File.Exists(enumerator.Current))
{
return true;
}
}
}
string[] array = System.Environment.GetEnvironmentVariable("PATH").Split(':', StringSplitOptions.None);
for (int i = 0; i < array.Length; i++)
{
if (File.Exists(Path.Combine(array[i], "su")))
{
return true;
}
}
foreach (ActivityManager.RunningAppProcessInfo runningAppProcessInfo in ActivityManager.FromContext(Forms.Context).RunningAppProcesses)
{
if (runningAppProcessInfo.ProcessName.Contains("supersu") || runningAppProcessInfo.ProcessName.Contains("superuser"))
{
return true;
}
}
return false;
}
// Token: 0x06000046 RID: 70 RVA: 0x00008240 File Offset: 0x00006440
public bool IsProperUtcFormat()
{
return Build.Tags.Contains("test-keys");
}
// Token: 0x06000047 RID: 71 RVA: 0x00008251 File Offset: 0x00006451
public bool IsMonthCorrect()
{
return (Forms.Context.ApplicationContext.ApplicationInfo.Flags & ApplicationInfoFlags.Debuggable) > ApplicationInfoFlags.None;
}
// Token: 0x06000048 RID: 72 RVA: 0x0000826C File Offset: 0x0000646C
public bool IsCurrentMonth()
{
return Debug.IsDebuggerConnected;
}
// Token: 0x06000049 RID: 73 RVA: 0x00008274 File Offset: 0x00006474
public bool IsItReallyCurrentYearAlready()
{
foreach (ApplicationInfo applicationInfo in Forms.Context.PackageManager.GetInstalledApplications(PackageInfoFlags.MetaData))
{
string packageName = applicationInfo.PackageName;
if (packageName == "de.robv.android.xposed.installer" || packageName == "com.saurik.substrate" || packageName == "com.android.vending.billing.InAppBillingService.LUCK" || packageName == "com.android.vending.billing.InAppBillingService.CLON" || packageName == "com.android.vending.billing.InAppBillingService.COIN")
{
return true;
}
}
return false;
}
}
}
Szyfrowanie w Ruby
Usługa StringEncrypt została wzbogacona o szyfrowanie i generowanie kodu w języku programowania Ruby.
StringEncrypt pozwala na szybkie i sprawne zaszyfrowanie dowolnych stringów, każdorazowo generując inny algorytm szyfrujący dane, a na wyjściu zwraca kod deszyfrujący w wybranym języku programowania.
Dla czytelników Security News darmowy kod aktywacyjny, pozwalający skorzystać ze wszystkich dostępnych opcji szyfrujących:
CEB4-A1A7-797C-F65F
Pattern detectors – benchmark
Benchmark detektorów wzorców bajtowych, wykorzystywanych w hackach do gier:
https://github.com/learn-more/findpattern-bench
Oryginalna dyskusja na forum:
http://www.unknowncheats.me/forum/c-and-c/125497-findpattern-benchmark.html
EXE Packer dla .NET
.netshrink v2.3
.netshrink to kompresor (tzw. exe-packer) aplikacji .NET-owych, wykorzystujący kompresję LZMA
.netshrink to także DLL binder pozwalający scalić aplikację oraz jej dodatkowe moduły DLL do jednego pliku EXE:
Ostatnie zmiany:
v2.3
- dodana obsługa plików projektów
- dodana lista lokalnie zapisanych haseł
- usunięto błędy obsługi 64 bitowych aplikacji
v2.2
- zachowywanie oryginalnej architektury CPU w skompresowanych plikach
- poprawione uruchamianie assemblies ze ścieżek UNC (udziały sieciowe)
Strona domowa:
https://www.pelock.com/products/netshrink
Wersje demonstracyjną można ściągnąć z:
Setup:
https://www.pelock.com/download/netshrink.exe (713 kB)
Archiwum zip:
https://www.pelock.com/download/netshrink.zip (427 kB)




