q.m_bSprite.setPosition(3, getHeight() - 20);
q.m_bSprite.paint(g);
q._aStringI("Неверный ключ. Обратитесь за помощью на сайт www.tanchiki.ru"
, g, getWidth() - 15, getWidth() / 2, (getHeight() / 2 + q.m_agI) - 5, 1, true, true);
return;
}
[/quote]
То, что разработчики держали строки типа «Благодарим вас за регистрацию! Приятной игры!» в самом коде, очень облегчило нам задачу поиска, но так будет далеко не во всех играх. Чтобы регистрация прошла необходимо, чтобы переменная m_aI = 1.
Ищем все, что связано с изменением этой переменной в файле k.java.
И находим такой кусок кода:
[quote]
_L6:
int i = Integer.parseInt(m_aString);
boolean flag = false;
if(q.m_afI == 3)
{
long l;
String s;
long l1;
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = q.m_aeI)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
if((s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3)
* 3L + 2129L).substring(0, 7)).substring(0, 4).compareTo(m_aString.substring(1, 5)) == 0)
flag = true;
}
if(flag)
{
m_aI = 1;
q._aStringIV("temp", 2, i);
q.m_eZ = true;
} else
{
m_aI = 2;
}
this;
goto _L8
[/quote]
Переменная m_aI=1, если flag==true. А переменная flag принимает значение true, если выполняется довольно громоздкая и непонятная проверка ( разработчики постарались
).
В строчках:
[quote]
int i = Integer.parseInt(m_aString);
[/quote]
и
[quote]
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = q.m_aeI)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
[/quote]
видим 2 неизвестные переменные:
[quote]
m_aString
q.m_aeI
[/quote]
Сначала разберемся с q.m_aeI, так как l1 участвует в проверке кода.
Открываем q. java и ищем переменную m_ aeI. Мы находим ее только в строчке:
[quote]
public static int m_aeI = 0;
[/quote]
Но этого недостаточно, так как получается, что в k.java вызывается переменная из q.java, которая равна нулю… Следовательно, ищем изменение этой переменной в остальных классах.
В i.java находим такие строчки:
[quote]
int k;
if((k = q._aStringII("temp", 1, 0)) == 0){
k = q._aIII(0xf462b, 0x98967f);
k = 0x1c9c380 + k;
q._aStringIV("temp", 1, k);
}
q.m_aeI = k % 0x989680;
q.m_afI = (k - k % 0x989680) / 0x989680;
obj = String.valueOf(k);
obj = ((String) (obj)).substring(0, 4) + " " + ((String) (obj)).substring(4, 8);
[/quote]
Смотрим, какое значение получает переменная k при q._aIII(0xf462b, 0x98967f). Открываем q.java и ищем функцию _aIII
[quote]
public static int _aIII(int i, int x){
int i1;
return (i1 = Math.abs(m_aRandom.nextInt())) % (x - i) + i;
}
[/quote]
Исходя из этого переменной k задается случайное значение…
Проанализировав получаемые значения k, а так же исходя из этих строчек:
[quote]
obj = String.valueOf(k);
obj = ((String) (obj)).substring(0, 4) + " " + ((String) (obj)).substring(4, 8);
[/quote]
и
[quote]
q.m_bString = "T" + obj + " " + s;
[/quote]
Получаем, что k это первые 8 цифр из 12-значного кода, которые генерируется в игре при первом запуске.
[quote]
//вначале считываем код в переменную kod
//далее идет объединенные части из разных классов, которые мы раскопали
Kod1 = Kod % 0x989680;
obj = String.valueOf(Kod);
long l;
String s;
long l1;
boolean progress=true;
String Klych ="10000000";
while(progress){
Klych = String.valueOf(Integer.parseInt(Klych)+1);
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
if((s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3)
* 3L + 2129L).substring(0,7)).substring(0,4).compareTo(obj.substring(1, 5)) == 0){
progress=false;
//вывод переменной Klych
}
}
[/quote]
Для ускорения перебора можно вынести:
[quote]
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1)) + ... + 213L & 255L;
[/quote]
и
[quote]
String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3) * 3L + 2129L).substring(0, 7);
[/quote]
за цикл,так же можно установить "шаг перебора" равным 1000.
Получаем следующий код:
[quote]
Kod1=Kod % 0x989680;
long l;
String s;
String Klych ="10000000";
long l1;
boolean progress=true;
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3) * 3L + 2129L).substring(0, 7);
while(progress){
Klych = String.valueOf(Integer.parseInt(buf)+1000);
if ( s.substring(0, 4).compareTo(Klych.substring(1, 5)) == 0){
//вывод Klych
progress=false;
}
}
[/quote]
Теперь этот код можно перенести на любой другой язык программирования или оставить в J2ME.
Вместе со статьей идут два Key-Gen'а в котором он реализован… ( J2ME и VB.NET)
Вот так, просто анализируя код мы создали свой генератор ключей…
Генераторы ключей для Tanks Mobile 3.0:
q.m_bSprite.paint(g);
q._aStringI("Неверный ключ. Обратитесь за помощью на сайт www.tanchiki.ru"
, g, getWidth() - 15, getWidth() / 2, (getHeight() / 2 + q.m_agI) - 5, 1, true, true);
return;
}
[/quote]
То, что разработчики держали строки типа «Благодарим вас за регистрацию! Приятной игры!» в самом коде, очень облегчило нам задачу поиска, но так будет далеко не во всех играх. Чтобы регистрация прошла необходимо, чтобы переменная m_aI = 1.
Ищем все, что связано с изменением этой переменной в файле k.java.
И находим такой кусок кода:
[quote]
_L6:
int i = Integer.parseInt(m_aString);
boolean flag = false;
if(q.m_afI == 3)
{
long l;
String s;
long l1;
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = q.m_aeI)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
if((s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3)
* 3L + 2129L).substring(0, 7)).substring(0, 4).compareTo(m_aString.substring(1, 5)) == 0)
flag = true;
}
if(flag)
{
m_aI = 1;
q._aStringIV("temp", 2, i);
q.m_eZ = true;
} else
{
m_aI = 2;
}
this;
goto _L8
[/quote]
Переменная m_aI=1, если flag==true. А переменная flag принимает значение true, если выполняется довольно громоздкая и непонятная проверка ( разработчики постарались
В строчках:
[quote]
int i = Integer.parseInt(m_aString);
[/quote]
и
[quote]
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = q.m_aeI)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
[/quote]
видим 2 неизвестные переменные:
[quote]
m_aString
q.m_aeI
[/quote]
Сначала разберемся с q.m_aeI, так как l1 участвует в проверке кода.
Открываем q. java и ищем переменную m_ aeI. Мы находим ее только в строчке:
[quote]
public static int m_aeI = 0;
[/quote]
Но этого недостаточно, так как получается, что в k.java вызывается переменная из q.java, которая равна нулю… Следовательно, ищем изменение этой переменной в остальных классах.
В i.java находим такие строчки:
[quote]
int k;
if((k = q._aStringII("temp", 1, 0)) == 0){
k = q._aIII(0xf462b, 0x98967f);
k = 0x1c9c380 + k;
q._aStringIV("temp", 1, k);
}
q.m_aeI = k % 0x989680;
q.m_afI = (k - k % 0x989680) / 0x989680;
obj = String.valueOf(k);
obj = ((String) (obj)).substring(0, 4) + " " + ((String) (obj)).substring(4, 8);
[/quote]
Смотрим, какое значение получает переменная k при q._aIII(0xf462b, 0x98967f). Открываем q.java и ищем функцию _aIII
[quote]
public static int _aIII(int i, int x){
int i1;
return (i1 = Math.abs(m_aRandom.nextInt())) % (x - i) + i;
}
[/quote]
Исходя из этого переменной k задается случайное значение…
Проанализировав получаемые значения k, а так же исходя из этих строчек:
[quote]
obj = String.valueOf(k);
obj = ((String) (obj)).substring(0, 4) + " " + ((String) (obj)).substring(4, 8);
[/quote]
и
[quote]
q.m_bString = "T" + obj + " " + s;
[/quote]
Получаем, что k это первые 8 цифр из 12-значного кода, которые генерируется в игре при первом запуске.
Теперь объединяем все воедино и пишем подбор ключа
Используемые переменные:
Kod – первые 8 цифр из кода, который
генерируется при запуске игры
Kod1 – дополнительная переменная
[quote]
//вначале считываем код в переменную kod
//далее идет объединенные части из разных классов, которые мы раскопали
Kod1 = Kod % 0x989680;
obj = String.valueOf(Kod);
long l;
String s;
long l1;
boolean progress=true;
String Klych ="10000000";
while(progress){
Klych = String.valueOf(Integer.parseInt(Klych)+1);
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
if((s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3)
* 3L + 2129L).substring(0,7)).substring(0,4).compareTo(obj.substring(1, 5)) == 0){
progress=false;
//вывод переменной Klych
}
}
[/quote]
Для ускорения перебора можно вынести:
[quote]
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1)) + ... + 213L & 255L;
[/quote]
и
[quote]
String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3) * 3L + 2129L).substring(0, 7);
[/quote]
за цикл,так же можно установить "шаг перебора" равным 1000.
Получаем следующий код:
[quote]
Kod1=Kod % 0x989680;
long l;
String s;
String Klych ="10000000";
long l1;
boolean progress=true;
l1 = (l1 = Integer.parseInt((s = String.valueOf(l = Kod1)).substring(0, 1))
+ Integer.parseInt(s.substring(1, 2)) + Integer.parseInt(s.substring(2, 3))
+ Integer.parseInt(s.substring(3, 4)) + Integer.parseInt(s.substring(4, 5))
+ Integer.parseInt(s.substring(5, 6)) + Integer.parseInt(s.substring(6, 7))) * 321L + 213L & 255L;
s = String.valueOf(l = (l = (l = (l = (l = (l ^= 0x1c91bfL) ^ l1) ^ l1 << 8) ^ l1 << 16) << 3) * 3L + 2129L).substring(0, 7);
while(progress){
Klych = String.valueOf(Integer.parseInt(buf)+1000);
if ( s.substring(0, 4).compareTo(Klych.substring(1, 5)) == 0){
//вывод Klych
progress=false;
}
}
[/quote]
Теперь этот код можно перенести на любой другой язык программирования или оставить в J2ME.
Вместе со статьей идут два Key-Gen'а в котором он реализован… ( J2ME и VB.NET)
Вот так, просто анализируя код мы создали свой генератор ключей…
Генераторы ключей для Tanks Mobile 3.0:
Внимание! У вас нет прав для просмотра скрытого текста.
