Título: Descompilar / Desensamblar programa .NET
Publicado por: angel9484 en 16 Noviembre 2010, 15:50 pm
Buenas tardes, Se que puede parecer el tipico hilo donde pido que alguien me haga entero el trabajo o que me ayude a crackear un programa desconocido, pero quiero dar a entender que no es así. El programa en cuestión, es un programa en el que uno pone una clave de licencia, genera un código, que tu tienes que mandar a la empresa, y este te devuelve un codigo de retorno. La empresa en cuestión se ha ido al carajo, así que no existe y no se puede usar más que en los pc's que ya está instalado. Habian 3 ordenadores, pero resulta que en uno cambiamos el disco duro, clonamos el sistema, y al ejecutar el programa resultó que no funcionaba asi que descompilandolo con .NET Reflector vi que el codigo que se generaba tomaba el num de serie del disco duro como parte para generar el código. Todos los códigos se almacenan en el registro de Windows, pero antes de mirar ahi comprueba que concuerda, así que transportando las claves símplemente, no vale. Mi gran problema, es que he podido descompilarlo (no es muy dificil con el .NET Reflector), intento coger los cachos que me son de utilidad de código para que me devuelva el código de retorno, pero el primer problema es que hay una linea: buffer(i) = CByte(valor.Chars(i)) que luego en Visual Studio 2005 me dice que eso no puede ser, y tengo que usar Val o AsciW si no recuerdo mal, para hacer ese "casting". Lo hago y bueno, sale un código y tal, lo pongo y no es el bueno, así que hice una traza, y dependiendo de qué funcion ponga (Val o AsciW), me devuelve un valor u otro, asi que me da por pensar que el programa por dentro, haciendo la linea esa, tambien me devuelve algo diferente, y por eso no soy capaz de averiguar la clave.
¿Sabeis que puede pasar o que puedo hacer para resolver esto? No sé si me he equivocado de subforo, como no he visto algo de "cracking" concretamente puesto he ido al lenguaje en el que aparentemente está escrito el programa. Puedo aportar todas las funciones y procedimientos que se encargan de generar el código, pero el programa en sí no puedo ya que se comunica con un servidor para generar estadísticas y comprometería la seguridad de mi empresa.
muchas gracias, y espero que alguien pueda ayudarme!
Título: Re: Descompilar / Desensamblar programa .NET
Publicado por: raul338 en 16 Noviembre 2010, 16:12 pm
Esto deberia ir a la sección de .net (https://foro.elhacker.net/net-b62.0/)
Y para
buffer(i) = CByte(valor.Chars(i))
tenes Byte.Parse o Convert.ToByte :)
Título: Re: Descompilar / Desensamblar programa .NET
Publicado por: angel9484 en 25 Noviembre 2010, 18:41 pm
Buenas, siento haber tardado tantisimo en contestar... pero la uni no perdona. EDITO: Despues de darle algunas vueltas, habia pensado en descompilar el .exe y cambiarle diréctamente desde el ensamblador la parte en la que controla el registro, y saltarme directamente la clave, o que imprima la clave en el registro en lugar de buscarlo, y se autoregistre, pero soy incapacisimo de encontrar un programa para hacerlo o en el caso de ollydbg, de hacer algo a derechas (el debug produce excepciones despues de llamar a sitios tan dispares como kernel o win32, jamas consigo que me saque el codigo de mi "discoverymail.exe"No me funcionó el Parse ni el ToByte. Hay un método que llama a un método de un objeto creado de la clase MD5 (ComputeHash) y le da, supuestamente, lo que mete buffer(i) = CByte(valor.Chars(i)) valor es una cadena que es como el código a darle a la "empresa" (que vuelvo a anticipar que ya no existe). Estoy casi seguro de que es este método es el que lo lía todo, y no se si es que usa versiones anteriores/posteriores del framework .net y por eso esa linea en la compilacion de su momento era valida. Como hice un codigo para hacer la traza de lo que iba haciendo para hallar el codigo de retorno (luego al verlo ineficaz busque que hiciese el mismo codigo que esto me retorna, sin exito), puedo pegarlo aquí sin comprometer a la empresa: Código del fichero principal Imports System.Security.Cryptography Imports Microsoft.Win32 Public Class Form1 Shared idCompany As String = "30E35072EG3A" Shared clave As String = "5GD72G5E9GE9" Public Function GetDiscoveryMailConfigKey() As RegistryKey Dim key As RegistryKey Try key = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("DiscoveryMail", True) If (key Is Nothing) Then key = Registry.LocalMachine.OpenSubKey("Software", True).CreateSubKey("DiscoveryMail") End If Catch obj As System.Exception Return Nothing End Try Return key End Function Public Function GetCompany() As String If (idCompany <> "") Then Return idCompany End If Dim discoveryMailConfigKey As RegistryKey = Me.GetDiscoveryMailConfigKey If (discoveryMailConfigKey Is Nothing) Then MessageBox.Show("Error al acceder al registro. Compruebe que tenga permisos suficientes.") Return "" End If If (Not discoveryMailConfigKey.GetValue("CompanyId") Is Nothing) Then idCompany = CStr(discoveryMailConfigKey.GetValue("CompanyId")) Return idCompany End If Return Me.SetCompanyId End Function Public Function SetCompanyId() As String Dim discoveryMailConfigKey As RegistryKey = Me.GetDiscoveryMailConfigKey If (discoveryMailConfigKey Is Nothing) Then MessageBox.Show("Error al acceder al registro") Return "" End If discoveryMailConfigKey.SetValue("CompanyId", idCompany) Return idCompany End Function Public Function GetLicenseQuestion() As String Dim serial As New HardDriveSerial Return Me.md5((Me.GetCompany & "DiscoveryMail" & serial.Serial), 12) End Function Private Function toHex(ByVal a As Integer) As String If (a < 10) Then Return Convert.ToString(a) End If Select Case a Case 10 Return "A" Case 11 Return "B" Case 12 Return "C" Case 13 Return "D" Case 14 Return "E" End Select Return "F" End Function Public Function CheckIsValidLicense(ByVal license As String) As Boolean MessageBox.Show(Me.md5(("47619549" & Me.GetLicenseQuestion & "DiscoveryMail"), 12)) Return (Me.md5(("47619549" & Me.GetLicenseQuestion & "DiscoveryMail"), 12) = license) End Function Public Function md5(ByVal valor As String) As String Return Me.md5(valor, 0) End Function Public Function md5(ByVal valor As String, ByVal length As Integer) As String Dim md As MD5 = New MD5CryptoServiceProvider Dim buffer As Byte() = New Byte(valor.Length - 1) {} Dim i As Integer For i = 0 To valor.Length - 1 'buffer(i) = CByte(valor.Chars(i)) El original buffer(i) = CByte(AscW(valor.Chars(i))) 'El más adaptado al código 'buffer(i) = CByte(Byte.Parse(valor.Chars(i))) Lo del foro Next i Dim buffer2 As Byte() = md.ComputeHash(buffer) Dim text As String = "" Dim j As Integer For j = 0 To buffer2.Length - 1 Dim num2 As Integer = buffer2(j) Dim a As Integer = (num2 Mod &H10) Dim num3 As Integer = (num2 / &H10) text = (text & Me.toHex(a) & Me.toHex(num3)) Next j If (text.Length > 0) Then text = Me.reduceText(text, 12) End If Return text End Function Private Function reduceText(ByVal text As String, ByVal length As Integer) As String Dim str As String = "0KAL1MBN2OCP3QDR4SET5UFV6WGX7YHZ8I9J" Dim num4 As Integer = 0 Do While (text.Length > length) Dim ch As Char = text.Chars((text.Length - 1)) text = text.Substring(0, (text.Length - 1)) Dim ch2 As Char = text.Chars(num4) Dim index As Integer = str.IndexOf(ch2) Dim num2 As Integer = str.IndexOf(ch) Dim num3 As Integer = ((index + num2) Mod str.Length) text = (text.Substring(0, num4) & str.Chars(num3) & text.Substring((num4 + 1), ((text.Length - num4) - 1))) num4 += 1 If (num4 > length) Then num4 = 0 End If Loop Return text End Function Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAccept.Click If (Me.txtLicencia.Text.Length = 12) Then If Me.CheckIsValidLicense(Me.txtLicencia.Text) Then Me.btnAccept.Enabled = True Else Me.btnAccept.Enabled = False End If End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Me.CheckIsValidLicense(Me.txtLicencia.Text) MessageBox.Show(GetLicenseQuestion()) Me.Dispose() End Sub End Class
codigo es lo que estoy intentando sacar en el messagebox Serial es esto: Imports System.Management Friend Class HardDriveSerial ' Methods Public Function Serial() As String Dim list As New ArrayList 'Dim coge As String = "None" Dim searcher As New ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive") Dim obj2 As ManagementObject For Each obj2 In searcher.Get Dim drive As New HardDrive drive. Model = obj2. Item("Model"). ToString drive. Type = obj2. Item("InterfaceType"). ToString 'coge = obj2.Item("Signature").ToString() Next searcher = New ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia") Dim num As Integer = 0 Dim obj3 As ManagementObject For Each obj3 In searcher.Get Dim drive2 As HardDrive = DirectCast(list.Item(num), HardDrive) If (obj3.Item("SerialNumber") Is Nothing) Then drive2.SerialNo = "None" 'drive2.SerialNo = coge Else drive2.SerialNo = obj3.Item("SerialNumber").ToString End If num += 1 Next If (list.Count > 0) Then Return DirectCast(list.Item(0), HardDrive).SerialNo End If Return "NoDisc" End Function End Class
Los comentarios evidentemente son mios,estaba sacando el numero de serie del disco duro de una forma alternativa a ver si era eso, pero ni sacandolo con Signature lo hace bien, luego probé con otro programa que lo saca tambien con WMI y tanto en este como ese programa externo ponia "None" asi que descarté este problema. Y este es HardDrive Friend Class HardDrive ' Properties Public Property Model() As String Get Return Me.model2 End Get Set(ByVal value As String) Me.model2 = value End Set End Property Public Property SerialNo() As String Get Return Me.serialNo2 End Get Set(ByVal value As String) Me.serialNo2 = value End Set End Property Public Property Type() As String Get Return Me.type2 End Get Set(ByVal value As String) Me.type2 = value End Set End Property ' Fields Private model2 As String Private serialNo2 As String Private type2 As String End Class
Modifiqué las variables privadas y los Me.---- con ese 2 que se ve porque me decia algo de noseque recursivo, pero esta comprobado que pone y devuelve los valores bien ¿Algúna idea?
|