Реверсинг. Задай вопрос - получи ответ

Discussion in 'Реверсинг' started by 0x0c0de, 2 Sep 2007.

  1. Грот

    Грот Elder - Старейшина

    Joined:
    24 Jan 2008
    Messages:
    110
    Likes Received:
    36
    Reputations:
    0
    не совсем понял где и у какого плагина, AdvancedOlly v1.26?
     
  2. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    >> не совсем понял где и у какого плагина, AdvancedOlly v1.26?

    да, да. авансед0лли.
     
    1 person likes this.
  3. FreeRunner

    FreeRunner New Member

    Joined:
    10 Feb 2008
    Messages:
    3
    Likes Received:
    2
    Reputations:
    -5
    00401090 |. 68 FF000000 PUSH 0FF ; /Count = FF (255.)
    00401095 |. 68 1A304000 PUSH Creakme.0040301A ; |Buffer = Creakme.0040301A
    0040109A |. 68 EB030000 PUSH 3EB ; |ControlID = 3EB (1003.)
    0040109F |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
    004010A2 |. E8 F5000000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
    004010A7 |. 68 FF000000 PUSH 0FF ; /Count = FF (255.)
    004010AC |. 68 14304000 PUSH Creakme.00403014 ; |Buffer = Creakme.00403014
    004010B1 |. 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
    004010B6 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
    004010B9 |. E8 DE000000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA




    004010FE /$ 33C0 XOR EAX,EAX
    00401100 |. 33DB XOR EBX,EBX
    00401102 |. 33C9 XOR ECX,ECX
    00401104 |. A3 39304000 MOV DWORD PTR DS:[403039],EAX
    00401109 |> 33DB /XOR EBX,EBX
    0040110B |. 8A98 14304000 |MOV BL,BYTE PTR DS:[EAX+403014]
    00401111 |. 80FB 5A |CMP BL,5A
    00401114 |. 75 02 |JNZ SHORT Creakme.00401118
    00401116 |. FECB |DEC BL
    00401118 |> 80FB 7A |CMP BL,7A
    0040111B |. 75 02 |JNZ SHORT Creakme.0040111F
    0040111D |. FECB |DEC BL
    0040111F |> 80FB 39 |CMP BL,39
    00401122 |. 75 02 |JNZ SHORT Creakme.00401126
    00401124 |. FECB |DEC BL
    00401126 |> 50 |PUSH EAX
    00401127 |. 83C0 61 |ADD EAX,61
    0040112A |. 02F8 |ADD BH,AL
    0040112C |. 58 |POP EAX
    0040112D |. 80C3 01 |ADD BL,1
    00401130 |. 66:8B0C45 1A30>|MOV CX,WORD PTR DS:[EAX*2+40301A]
    00401138 |. 40 |INC EAX
    00401139 |. 50 |PUSH EAX
    0040113A |. 66:3BD9 |CMP BX,CX
    0040113D |. 75 37 |JNZ SHORT Creakme.00401176
    0040113F |. 8305 39304000 >|ADD DWORD PTR DS:[403039],1
    00401146 |. 58 |POP EAX
    00401147 |. 3B05 25304000 |CMP EAX,DWORD PTR DS:[403025]
    0040114D |.^75 BA \JNZ SHORT Creakme.00401109
    0040114F |. 50 PUSH EAX
    00401150 |. A1 39304000 MOV EAX,DWORD PTR DS:[403039]
    00401155 |. 3B05 25304000 CMP EAX,DWORD PTR DS:[403025]
    0040115B |. 58 POP EAX
    0040115C |. 75 18 JNZ SHORT Creakme.00401176
    0040115E |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
    00401160 |. 68 5F204000 PUSH Creakme.0040205F ; |Title = ".:: DiS[IP] Programer ::."
    00401165 |. 68 4A204000 PUSH Creakme.0040204A ; |Text = "Register complite!!!"
    0040116A |. FF35 00304000 PUSH DWORD PTR DS:[403000] ; |hOwner = NULL
    00401170 |. E8 33000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
    00401175 |. C3 RETN
    00401176 |> 58 POP EAX
    00401177 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
    00401179 |. 68 5F204000 PUSH Creakme.0040205F ; |Title = ".:: DiS[IP] Programer ::."
    0040117E |. 68 30204000 PUSH Creakme.00402030 ; |Text = "Name or Password is BAD!!"
    00401183 |. FF35 00304000 PUSH DWORD PTR DS:[403000] ; |hOwner = NULL
    00401189 |. E8 1A000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
    0040118E \. C3 RETN


    кто сможет Пошаго обьяснить что делает код с моим именим. Я понял что он смотрим если буква = z или Z. Если да он то он прыгает через Дикриз если нет то уменьшает значение на один байт. дальше я вроде понял но полюбому как реверсить всё это чтоб узнать какой Пасс он делает из Логина , хз.

    пасиб
     
  4. z01b

    z01b Муджахид

    Joined:
    5 Jan 2007
    Messages:
    494
    Likes Received:
    382
    Reputations:
    22
    2 FreeRunner, мона сылку на crackme?
     
  5. FreeRunner

    FreeRunner New Member

    Joined:
    10 Feb 2008
    Messages:
    3
    Likes Received:
    2
    Reputations:
    -5
    Сюда

    или Сюда
     
    #65 FreeRunner, 10 Feb 2008
    Last edited: 10 Feb 2008
  6. z01b

    z01b Муджахид

    Joined:
    5 Jan 2007
    Messages:
    494
    Likes Received:
    382
    Reputations:
    22
    Code:
    #include "stdafx.h"
    #include "windows.h" // Для sleep()
    
    int v1,v2,v3=0,i,len;
    char name[255];
    char v4[255];
    main(void)
    {
    	printf("Name : ");
    	scanf("%s",&name);
    	len = strlen(name);
    	if (len>3)
    	{
    		for (i=0; i<len; i++)
    		{
    			v3 = name[i];
    			if  ((name[i]=='z')||(name[i]=='Z')||(name[i]=='9')) v3=name[i]-1;
    			v1=0x61+i;
    			v2=v3+1;
    			v4[2*i]=v1;
    			v4[2*i+1]=v2;
    			v3=0;
    		}
    		printf("Serial : ");
    		for (i=0; i<len; i++) printf("%c%c",v4[2*i+1],v4[2*i]);
    	}
    	else printf("Name must be more than 3 chars.");
    Sleep(3000);
    return 0;
    }
    
    Будет время, отпишу асм код.

    Скомпиленый вариант http://slil.ru/25457249
     
    #66 z01b, 10 Feb 2008
    Last edited: 10 Feb 2008
  7. z01b

    z01b Муджахид

    Joined:
    5 Jan 2007
    Messages:
    494
    Likes Received:
    382
    Reputations:
    22
    Вот как обещал прокомментированый код
    Code:
    004010FE /$ 33C0 XOR EAX,EAX;обнулили регистры
    00401100 |. 33DB XOR EBX,EBX;
    00401102 |. 33C9 XOR ECX,ECX;
    00401104 |. A3 39304000 MOV DWORD PTR DS:[403039],EAX; обнулили переменную
    00401109 |> 33DB /XOR EBX,EBX; обнулили ebx
    0040110B |. 8A98 14304000 |MOV BL,BYTE PTR DS:[EAX+403014]; берем символ из имени и пихаем в BL
    00401111 |. 80FB 5A |CMP BL,5A; если BL != 5A('Z')
    00401114 |. 75 02 |JNZ SHORT Creakme.00401118; прыгаем на 401118
    00401116 |. FECB |DEC BL; иначе вычитываем один из BL
    00401118 |> 80FB 7A |CMP BL,7A;если BL != ('z')
    0040111B |. 75 02 |JNZ SHORT Creakme.0040111F; прыгаем на 40111F
    0040111D |. FECB |DEC BL; иначе вычитываем один из BL
    0040111F |> 80FB 39 |CMP BL,39;если BL != ('9')
    00401122 |. 75 02 |JNZ SHORT Creakme.00401126;прыгаем на 401126
    00401124 |. FECB |DEC BL; иначе вычитываем один из BL
    00401126 |> 50 |PUSH EAX; заносим eax в стэк
    00401127 |. 83C0 61 |ADD EAX,61; прибавляем ему 61
    0040112A |. 02F8 |ADD BH,AL; пихаем в BH один из символов сериала
    0040112C |. 58 |POP EAX; востонавливаем eax
    0040112D |. 80C3 01 |ADD BL,1; добавляем в BL один
    00401130 |. 66:8B0C45 1A30>|MOV CX,WORD PTR DS:[EAX*2+40301A]; Заносим две символы нашего сериала в CX
    00401138 |. 40 |INC EAX; добавляем один в eax
    00401139 |. 50 |PUSH EAX; сохраняем eax
    0040113A |. 66:3BD9 |CMP BX,CX; если слово (2 байта) из cx = слово из bx
    0040113D |. 75 37 |JNZ SHORT Creakme.00401176; не прыгаем на 401176
    0040113F |. 8305 39304000 >|ADD DWORD PTR DS:[403039],1; переменая = переменная + 1
    00401146 |. 58 |POP EAX; востанавливаем eax
    00401147 |. 3B05 25304000 |CMP EAX,DWORD PTR DS:[403025]; если eax = длина строки (переменная)
    0040114D |.^75 BA \JNZ SHORT Creakme.00401109; выходим из цикла, иначе повторяем его.
    0040114F |. 50 PUSH EAX
    00401150 |. A1 39304000 MOV EAX,DWORD PTR DS:[403039]
    00401155 |. 3B05 25304000 CMP EAX,DWORD PTR DS:[403025]
    0040115B |. 58 POP EAX
    0040115C |. 75 18 JNZ SHORT Creakme.00401176
    0040115E |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
    00401160 |. 68 5F204000 PUSH Creakme.0040205F ; |Title = ".:: DiS[IP] Programer ::."
    00401165 |. 68 4A204000 PUSH Creakme.0040204A ; |Text = "Register complite!!!"
    0040116A |. FF35 00304000 PUSH DWORD PTR DS:[403000] ; |hOwner = NULL
    00401170 |. E8 33000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
    00401175 |. C3 RETN
    00401176 |> 58 POP EAX
    00401177 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
    00401179 |. 68 5F204000 PUSH Creakme.0040205F ; |Title = ".:: DiS[IP] Programer ::."
    0040117E |. 68 30204000 PUSH Creakme.00402030 ; |Text = "Name or Password is BAD!!"
    00401183 |. FF35 00304000 PUSH DWORD PTR DS:[403000] ; |hOwner = NULL
    00401189 |. E8 1A000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
    0040118E \. C3 RETN
    
     
    1 person likes this.
  8. whinger

    whinger New Member

    Joined:
    19 Feb 2008
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    Есть программа GeoCalck v1.4.
    Почему, когда я открываю в OllyDbg файл GeoCalck.exe и нажимаю F9, то отладчик останавливается и в статусной строке пишет:
    "Inexact floating-point result - use Shift+F7/F8/F9 to pass exception to program"
    Нажимаю Shift+F9, пишет там-же:
    "Access violation then reading [00000000] - use Shift+F7/F8/F9 to pass exception to program"
    И так при нажатии Shift+F9 опять повторяется то-же самое.
    Что делать и как быть?
    З.Ы. Если у кого-то есть готовый исходник кейгена для энтой проги, то прошу скинуть на [email protected] - поизучаю.
     
  9. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    2whinger
    Нажми Alt+O в OllyDbg, открой вкладку exceptions и поставь везде галочки
     
  10. void //tPORt

    void //tPORt New Member

    Joined:
    19 Feb 2008
    Messages:
    3
    Likes Received:
    1
    Reputations:
    0
    whinger, для начала скорми свой фаел DiE и PEiD и посмотри чем упаковано.
    Если весит какой либо пакер/прот сначало его снять предецо.
     
    1 person likes this.
  11. tekton

    tekton Elder - Старейшина

    Joined:
    2 Jun 2008
    Messages:
    73
    Likes Received:
    3
    Reputations:
    0
    Читал статью что можно прямо в проге сделать так, чтобы вместо сообщения о неправельном пароле показывался регистрационный код ( сделать типа примитивного кейгена). Знаю что для этого надо сперва найти пароль, я его нащёл. Как что делать дальше? Если можно поподробнее и на примерах, с участием малой части кода программы ;). Спасибо!
     
  12. BlackSun

    BlackSun Banned

    Joined:
    1 Apr 2007
    Messages:
    989
    Likes Received:
    1,168
    Reputations:
    446
    Ну если готовый пароль хранится в памяти .. допустим у тебя есть

    push hWnd
    push Title
    push Text
    push Type
    call MessageBoxA

    Где Text - текст, о неверном пароле
    и

    push TruePass
    ..
    и дальше функция проверки

    ты в мессадж боксе о неверном пароле смени

    push Text
    на
    push TruePass

    и будет тебе щястье)) а вообше моски руляд, импровизируй
     
  13. tekton

    tekton Elder - Старейшина

    Joined:
    2 Jun 2008
    Messages:
    73
    Likes Received:
    3
    Reputations:
    0
    BlackSun спасибо. Вот код. (Прога написана на делфи)

    0048DA8C /$ 55 PUSH EBP
    0048DA8D |. 8BEC MOV EBP,ESP
    0048DA8F |. 6A 00 PUSH 0
    0048DA91 |. 6A 00 PUSH 0
    0048DA93 |. 6A 00 PUSH 0
    0048DA95 |. 6A 00 PUSH 0
    0048DA97 |. 6A 00 PUSH 0
    0048DA99 |. 53 PUSH EBX
    0048DA9A |. 56 PUSH ESI
    0048DA9B |. 894D F8 MOV DWORD PTR SS:[EBP-8],ECX
    0048DA9E |. 8955 FC MOV DWORD PTR SS:[EBP-4],EDX
    0048DAA1 |. 8BF0 MOV ESI,EAX
    0048DAA3 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
    0048DAA6 |. E8 D570F7FF CALL КЕЙ_ГЕН.00404B80
    0048DAAB |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
    0048DAAE |. E8 CD70F7FF CALL КЕЙ_ГЕН.00404B80
    0048DAB3 |. 33C0 XOR EAX,EAX
    0048DAB5 |. 55 PUSH EBP
    0048DAB6 |. 68 86DB4800 PUSH КЕЙ_ГЕН.0048DB86
    0048DABB |. 64:FF30 PUSH DWORD PTR FS:[EAX]
    0048DABE |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
    0048DAC1 |. 33DB XOR EBX,EBX
    0048DAC3 |. BA A0DB4800 MOV EDX,КЕЙ_ГЕН.0048DBA0 ; ASCII "Megido,share.homedns.org,www.appzplanet.com"
    0048DAC8 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
    0048DACB |. E8 0472F7FF CALL КЕЙ_ГЕН.00404CD4
    0048DAD0 |. 85C0 TEST EAX,EAX
    0048DAD2 |. 7E 0B JLE SHORT КЕЙ_ГЕН.0048DADF
    0048DAD4 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
    0048DAD7 |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
    0048DADA |. E8 996CF7FF CALL КЕЙ_ГЕН.00404778
    0048DADF |> 8D4D F4 LEA ECX,DWORD PTR SS:[EBP-C]
    0048DAE2 |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
    0048DAE5 |. 8BC6 MOV EAX,ESI
    0048DAE7 |. E8 60010000 CALL КЕЙ_ГЕН.0048DC4C
    0048DAEC |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
    0048DAEF |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
    0048DAF2 |. E8 ADAFF7FF CALL КЕЙ_ГЕН.00408AA4
    0048DAF7 |. 85C0 TEST EAX,EAX
    0048DAF9 |. 75 41 JNZ SHORT КЕЙ_ГЕН.0048DB3C
    0048DAFB |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
    0048DAFE |. 8BC6 MOV EAX,ESI
    0048DB00 |. E8 9FF3FFFF CALL КЕЙ_ГЕН.0048CEA4
    0048DB05 |. 84C0 TEST AL,AL
    0048DB07 |. 74 62 JE SHORT КЕЙ_ГЕН.0048DB6B
    0048DB09 |. B3 01 MOV BL,1
    0048DB0B |. 6A 40 PUSH 40
    0048DB0D |. 8D55 F0 LEA EDX,DWORD PTR SS:[EBP-10]
    0048DB10 |. A1 E4EF4B00 MOV EAX,DWORD PTR DS:[4BEFE4]
    0048DB15 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
    0048DB17 |. E8 DC96FDFF CALL КЕЙ_ГЕН.004671F8
    0048DB1C |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
    0048DB1F |. E8 6C70F7FF CALL КЕЙ_ГЕН.00404B90
    0048DB24 |. 50 PUSH EAX ; |Title
    0048DB25 |. 68 CCDB4800 PUSH КЕЙ_ГЕН.0048DBCC ; |Text = "Registration success, Thanks for your registration."
    0048DB2A |. A1 E4EF4B00 MOV EAX,DWORD PTR DS:[4BEFE4] ; |
    0048DB2F |. 8B00 MOV EAX,DWORD PTR DS:[EAX] ; |
    0048DB31 |. 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30] ; |
    0048DB34 |. 50 PUSH EAX ; |hOwner
    0048DB35 |. E8 1E9BF7FF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
    0048DB3A |. EB 2F JMP SHORT КЕЙ_ГЕН.0048DB6B
    0048DB3C |> 6A 10 PUSH 10
    0048DB3E |. 8D55 EC LEA EDX,DWORD PTR SS:[EBP-14]
    0048DB41 |. A1 E4EF4B00 MOV EAX,DWORD PTR DS:[4BEFE4]
    0048DB46 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
    0048DB48 |. E8 AB96FDFF CALL КЕЙ_ГЕН.004671F8
    0048DB4D |. 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
    0048DB50 |. E8 3B70F7FF CALL КЕЙ_ГЕН.00404B90
    0048DB55 |. 50 PUSH EAX ; |Title
    0048DB56 |. 68 00DC4800 PUSH КЕЙ_ГЕН.0048DC00 ; |Text = "Invalid Registration Code!
    Please enter an available Registration Code."
    0048DB5B |. A1 E4EF4B00 MOV EAX,DWORD PTR DS:[4BEFE4] ; |
    0048DB60 |. 8B00 MOV EAX,DWORD PTR DS:[EAX] ; |
    0048DB62 |. 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30] ; |
    0048DB65 |. 50 PUSH EAX ; |hOwner = 0007061C ('¦+г ++=',class='TApplication')
    0048DB66 |. E8 ED9AF7FF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA

    Куда ни пишу, OLLY пишет: "Extra input after operand" . Может обьяснишь на примере этого кода.
     
  14. BlackSun

    BlackSun Banned

    Joined:
    1 Apr 2007
    Messages:
    989
    Likes Received:
    1,168
    Reputations:
    446
    Скинь лудше ссыль на прогу
     
  15. tekton

    tekton Elder - Старейшина

    Joined:
    2 Jun 2008
    Messages:
    73
    Likes Received:
    3
    Reputations:
    0
    Прога называется 4U WMA MP3 Converter v3.1.5. Сейчас поищу в нете, т.к. брал у приятеля.
     
  16. BlackSun

    BlackSun Banned

    Joined:
    1 Apr 2007
    Messages:
    989
    Likes Received:
    1,168
    Reputations:
    446
    Лан, завтра гляну, напишу, а щяс спать, время почти 3 ночи)
     
  17. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    1. Нужно использовать теги CODE
    2. Нужно рипать код
    3. Для таких кусков нужно либо помечать комментариями важные части, либо использовать pastbin для подсветки синтаксиса

    Это можно сделать в любом случае хранится пароль в памяти или нет... правда если он там не хранится придется модифицировать программу во многих местах и добавлять свои функции для преобразованию к ASCII и выводу на экран(это смотря чего не хватает)! Вобщем это очень муторно! Вот если он хранится в памяти, то нет проблем! Просто меняем адрес титла у MessageBoxA на адрес полученного пароля и все... Спрашивается: Че у тя там в кодексе, что ты скинул? А нужно ли тебе это?
     
  18. BlackSun

    BlackSun Banned

    Joined:
    1 Apr 2007
    Messages:
    989
    Likes Received:
    1,168
    Reputations:
    446
    На примере 4U WMA MP3 Audio Converter v5.6.0 (другую версию не нашел, слить мона с http://thepiratebay.org/ ) и с помошью дебагера OllyDbg (или просто Оля)

    По адрессу 0048D458 - процедура проверки введенного пароля
    По адрессу 0048D4B8 видим MOV EDX,DWORD PTR SS:[EBP-C] - наш труЪ пароль
    По адрессу 0048D4D6 видим условие, если пароль не подходит - прыгаем на <bad_msg>
    <bad_msg> - валяется по адрессу 0048D50B
    По адрессу 0048D525 push <bad_registration code>
    Меняем на
    PUSH DWORD PTR SS:[EBP-C]
    nop
    nop

    Затем Copy to executable -> All modifications -> Копировать все -> Save file -> keygen.exe

    Все, кейген из проги готов :) вводишь свое имя, любой пароль, жмешь register, получаешь пароль ..

    Name: BlackSun
    Code: 0E031-959CA-29DD3-3A0E3-03195

    Happy End =)

    PS: каг домашнее задание тебе - сделать, чтобы код показывался не в MessageBox'е, а в Edit, + обрезать лишние ресуры, сжать, ну или норм кейген сварить))
     
    1 person likes this.
  19. ntldr

    ntldr Elder - Старейшина

    Joined:
    4 Dec 2007
    Messages:
    367
    Likes Received:
    140
    Reputations:
    23
    Можно ли подменить api-функцию LoadLibraryA путем редактирования таблицы импорта и изменению kernel32.dll на мою dll?(без сплайсинга) если можно, то как?
     
  20. BlackSun

    BlackSun Banned

    Joined:
    1 Apr 2007
    Messages:
    989
    Likes Received:
    1,168
    Reputations:
    446
    Все можно, если осторожно :) но проше сплайсингом .. пиши свою kernel32.dll (можно просто переходинки) называй по своему, кидай в папку с прогой и в импорте меняй kernel32.dll на свою .. имхо. И вообше зачем именно так? всегда мона найти более простые способы