Ayuda Launcher

Iniciado por motorhead1864, 11 Diciembre 2017, 20:53 PM

0 Miembros y 2 Visitantes están viendo este tema.

motorhead1864

Buenas.

Les cuento:

Estoy trabajando en un servidor de Lineage II y me gustaría darle un toque mas personalizado y la ves darle un poco mas de protección con un launcher.

Necesito saber si hay alguna forma de que el ejecutable del juego (L2.exe) NO se pueda abrir si no es desde mi launcher.

La verdad soy bastante nuevo en el tema de crear aplicaciones.

No se si es posible hacer lo que necesito, y si lo es, no se cual seria la manera mas adecuada de hacerlo.

Espero que alguien puede ayudarme en el tema.

De antemano gracias!!.

Saludos.



Eleкtro

#1
Cita de: motorhead1864 en 11 Diciembre 2017, 20:53 PMNecesito saber si hay alguna forma de que el ejecutable del juego (L2.exe) NO se pueda abrir si no es desde mi launcher.

¿Quieres restringir la ejecución de un executable de forma global en el sistema operativo del usuario?. Eso nunca es buena idea... a menos que seas el administrador de un cybercafé o similar.

Yo en tu lugar me replantearia la situación, aun así, te respondo a tu pregunta:




- Una forma sería mediante un API hook.
Pros:

  • Puedes analizar el executable de la forma que quieras (el nombre del archivo, los bytes, la versión, etc) para decidir si debe ejecutarse o no. Basicamente estás controlando la funcionalidad nativa de Windows para el inicio/creación de un proceso.
Contras:

  • Cualquier tipo de hook está considerado una metodología muy intrusiva para el usuario, no te darán las gracias por que a nadie le gustan las restricciones, y menos las de este tipo.
  • Si se implementa mal puede ralentizar el sistema operativo según en qué escenarios.
  • Requiere desarrollar un servicio de Windows (o en su defecto tu programa corriendo las 24 hrs. en segundo plano) para que el hook sea persistente y afecte a los nuevos procesos creados.
  • VB6 es una mala opción como lenguaje de programación para intentar llevar esto a cabo. (deberías apañártelas para implementar wrappers de las funciones de la API de Microsoft Detours para C/C++, en VB6)

Aquí tienes un ejemplo que escribí en VB.NET de un API hook de la librería Kernel32.dll para filtrar las llamadas de la función CreateProcessW:
( pero con solamente eso no te bastará para ser efectivo, debes implementar lo que comentó el usuario @ThunderCls )




- Otra forma sería mediante las políticas de grupo del sistema, la clave de registro DisallowRun: https://technet.microsoft.com/en-us/library/cc960900.aspx
Pros:

  • Es sencillo de aplicar en cualquier lenguaje de programación, ya que solo necesitas tener conocimientos para manipular el registro de Windows de forma programática.
  • No es tan intrusivo como la otra opción.
Contras:

  • Solo puedes restringir la ejecución de un executable por su nombre de archivo, es decir, el usuario puede cambiar el nombre del executable para bypassear tu sistema de restricción.
  • Un usuario con un mínimo de conocimiento informático puede borrar la política de usuario que bloquea el uso del executable. (pues solo hay que borrar una clave de registro)
  • Los cambios en el registro de Windows para aplicar este tipo de restricción requieren de un cierre de sesión de usuario o en su defecto un reinicio del PC para que tenga efecto. (sin embargo, esto se puede evitar usando ciertas funciones de la API de Windows para actualizar el estado de las políticas de usuario)

Un ejemplo sería el siguiente:
Script.reg
Código (ini) [Seleccionar]
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer]
"DisallowRun"=dword:00000001

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun]
"1"="L2.exe"





- Otra opción seria mediante la manipulación de permisos de usuario sobre el exeutable para impedir la lectura/ejecución del archivo, pero en mi opinión ni merece la pena mencionarlo por que cualquiera sin experiencia buscando en Google puede descubrir métodos y software para restaurar permisos / "desbloquear" archivos restringidos por este método.




Probablemente habrá más opciones y puede que mejores, yo te he mencionado la que considero mejor opción pero más compleja, y la que considero peor opción pero la más sencilla para cualquier nivel de conocimiento en programación.

Saludos.








Serapis

Hay una sencilla forma, no costosa ni invasiva, pero igualmente restrictiva...

Crea tu ejecutable del juego, esperando un comando.... (command$)
Sólo cuando se reciba el comando específico, que arranque
por ejemplo:
lL2.exe /Play:xMnfi5689FgjEodf84W78sH34

Tu ejecutable deberá arrancar desde un módulo, no desde el formulario... y en Main, harías algo como:

En el módulo este código:
Código (vb) [Seleccionar]

Option Private Module

Private Const KeyPriv As String = "pH91jksdet4YU83ReWab..+gX"
Public Ok As String

#Const DebugP = True ' Poner a true, para generar una key oculta dadas dos keys; una privada aquí y otra en el ejecutable que invoca a éste.
                                  ' poner a false, cuando ya se haya generado, copiado y pegado en su sitio, para probar el funcionamiento, pero sobre todo para compilar...


Private Sub Main()
    Dim f As Form1
    Dim cm As String
    Dim k As Long
   
   
    If (Len(Command$) > 0) Then
        k = InStr(UCase$(Command$), "/PLAY:")
        If (k = 1) Then
            cm = Right$(Command$, Len(Command$) - Len("/play:"))
            #If DebugP Then
                On Local Error GoTo NoCompilar
                Call GenerarKeyOculta(cm)
            #End If
            On Local Error Resume Next ' otros errores no deben mostrar dicho mensaje...
            If VerificarKey(cm) = True Then
                Set f = New Form1
                f.Show 1  ' modal...
            End If
        End If
    End If
    Exit Sub
   
NoCompilar:
    MsgBox "Si ya ha generado y colocado la key oculta, y quiere compilar (o ha compilado) el proyecto debiera desactivar la función GenerarKeyOculta, poniendo DebugP a false"
End Sub

Private Function VerificarKey(ByRef Key As String) As Boolean
    Dim k1() As Byte, k2() As Byte, k3() As Byte
    Dim k As Long, n As Long
   
    k1 = StrConv(Key, vbFromUnicode)
    Debug.Print StrConv(k1, vbUnicode)
    k2 = StrConv(KeyPriv, vbFromUnicode)
    Debug.Print StrConv(k2, vbUnicode)
   
    k3 = StrConv("WW^E\\2S3WW4]c6U]cTl", vbFromUnicode)
    Debug.Print StrConv(k3, vbUnicode)
   
    For k = 0 To UBound(k1)
        If (k1(k) Xor k2(k)) <> k3(k) Then Exit Function
    Next
    Ok = CStr(Now)
    VerificarKey = True
End Function

' No puede formar parte del código del programa, solo durante diseño...
#If DebugP Then
Private Sub GenerarKeyOculta(ByRef Key As String)
    Dim k1() As Byte, k2() As Byte, k3() As Byte
    Dim k As Long, n As Long
   
    If (Len(Key) <> Len(KeyPriv)) Then
        Call Err.Raise(vbObjectError + 1, "mi programa", "Las dos claves deben tener la misma cantidad de caracteres: (Key y KeyPriv))")
    Else
        k1 = StrConv(Key, vbUnicode)
        k2 = StrConv(KeyPriv, vbUnicode)
       
        ReDim k3(0 To UBound(k1))
        For k = 0 To UBound(k1)
            k3(k) = (k1(k) Xor k2(k))
        Next
       
        Debug.Print StrConv(k3, vbFromUnicode)
        Call MsgBox("Ahora puede copiar (de la ventana de debug) y pegar el valor resultante en 'k3' en la función 'VerificarKey'..." & vbCrLf & StrConv(k3, vbFromUnicode), vbExclamation, "Key oculta generada") 'strconv
    End If
End Sub
#End If


En el formulario, añadir un control Timer y colocar este código:
Código (vb) [Seleccionar]

Private Sub Form_Load()
    Randomize Timer
    Timer1.Interval = Int((30000 - 12000) * Rnd + 12000) ' espera un tiempo aleatorio entre 12 y 30 segundos...
    Timer1.Enabled = True
   
    ' otras cosas que requieran ser inicializadas...
End Sub

' Hace una comprobación posterior.
' Es muy básico simplemente busca si hay algún carac´ter 'raro' en el valor de 'ok'
'   el cual debiera tener solo caracteres propios de fecha y hora.
Private Sub Timer1_Timer()
    Dim salida As Boolean
    Dim s As String
   
    Timer1.Enabled = False
    If (Len(Module1.Ok) > 0) Then
        For k = 1 To Len(Module1.Ok)
            s = Mid$(Module1.Ok, k, 1)
            If (InStr("0123456789 :-\/", s) = 0) Then
                salida = True
                Exit For
            End If
        Next
    Else
        salida = True
    End If
   
    If (salida = True) Then End
End Sub


El funcionamiento es como sigue:
El módulo tiene una clave, por comando se le pasa otra key, luego una función verifica mediante un ximple xor, si se valida o no... adicionalmente se añade otra simple tontería de control si se parchea la función verificar para arrojar true sin ejecutarse, el formulario cuando arranca pone en marcha un timer con un intérvalo al azar entre 12 y 30 segundos, transcurrido el cual verifica si un texto generado cuando se ejecutó la función que verificaba la key, tiene texto y si el mismo es inválido.

NOTA: Que las keys debes generalas tú con cada versión, pon lo que te dé la gana pero que tengane l mismo tamaño, una vez creadas la que se pase por comando y la que se alamcene en KeyPriv, invocar la función GenerarKey, para tener la 3 contra la que se verifican las dos previas...

Ambas protecciones son muy elementales y fáciles de romper, pero si tu programa no va tener una popularidad fuera de serie, posiblemente sea suficiente...

Algo más elaborado es que tu proyecto sea una librería dll, que arranque luego el formulario principaly ya desde ahí tu programa se inicia. El programa que arranca el otro, crea una instancia de la librería y utiliza métodos "Friend", para hacer validaciones simples como las previas, solo que por métodos y propiedades directas, en vez de un comando que puede fácilmente ser interceptado por una aplicación que suplante la identidad de tu programa y/o se interponga en medio.



Opino como Elektro, es tontería... si publicas un ejecutable será para que sea usado, no para impedir que se use. Y si tu problema se resume en que alguien lo tome y luego lo publique como propio dentro de algo más, lo adecuado al caso, es forzar dependencias, así o se lo lleva todo o nada y si se lo lleva todo, ya no puede pasar desapercibido como 'suyo'... si lo que te preocupa es la autoría.

Eleкtro

#3
Cita de: NEBIRE en 13 Diciembre 2017, 03:31 AM
Hay una sencilla forma, no costosa ni invasiva, pero igualmente restrictiva...

Crea tu ejecutable del juego, esperando un comando.... (command$)
Sólo cuando se reciba el comando específico, que arranque
por ejemplo:
lL2.exe /Play:xMnfi5689FgjEodf84W78sH34

Compañero NEBIRE creo que entendiste mal el problema. Él no quiere "restringir" o condicionar el uso de su propio executable (en cuyo caso la solución que sugieres mediante el uso de argumentos command-line si que sería apropiada claro está).

...Desde el principio:

Lineage II es un juego MMORPG para PC, cuyo executable se llama "L2.exe". Este usuario lo que quiere hacer es restringir la ejecución de ese executable para que solo se pueda iniciar desde un "launcher" desarrollado en VB, desde su programa, vaya. Lo comento para evitar confusiones también a otros usuarios que se interesen en este thread.

Como ya comenté, esto a mi me parece un sin sentido aparente, y sobre todo muy intrusivo, descargar e instalar un juego o aplicación "A" para luego instalar otra aplicación addicional "B" que tenga la finalidad de restringir el uso de la aplicación "A" para que solo puedas iniciarla desde la aplicación "B", pero bueno, allá cada uno con sus motivos...

Saludos








Serapis

#4
jejeje... pués si, Elektro, entendí mal... con L2.exe suena simplemente a nombre de cualquier ejecutable que uno ha hecho... y que parece (parecía) indicar que subiría a alguna parte disponible para otros usuarios.

Creo que no leí el párrafo previo donde lo aclara bien...

motorhead1864

Entiendo lo que dicen, pero no creo que sera tan invasivo como lo plantean.

Ya que hoy en dia, para entrar a la gran mayoría de los servidores de lineage II solo hace falta reemplazar una carpeta en la raíz del juego (system). esta carpeta solo tiene archivos relacionados a la conexion y configuración del servidor a la que pertenece.
El l2.exe también se encuentra en esta carpeta. por ende es posible modificar es posible modificar archivos dentro de la carpeta system sin afectar de manera negativa el resto del juego, ya que si el jugador quiere cambiar de servidor, solo elimina la carpeta system y la reemplaza con otra de otro servidor.

habiendo dicho esto, no se si abra alguna forma de que Launcher detecte la ejecución del l2.exe y lo cierre si es que no se ejecuto vía launcher.

Otra forma  podría ser restringir la ejecución de la aplicación en la parte del servidor (el servidor esta escrito en java). pero no se si se pueda hacer.

Eleкtro

#6
Cita de: motorhead1864 en 13 Diciembre 2017, 16:47 PM
no se si abra alguna forma de que Launcher detecte la ejecución del l2.exe y lo cierre si es que no se ejecuto vía launcher.

1.
Al iniciar el executable L2.exe desde tu launcher, puedes activar el valor de un flag booleano (Dim flag As Boolean = True), y desactivarlo cuando finalice la ejecución del proceso, así sabrás en todo momento si L2.exe lo iniciaste tú o no... a menos que el proceso de L2.exe sea multi instancia, eso ya no lo sé, no lo he jugado nunca.

2.
En el caso de que L2.exe sea multi instancia, puedes aplicar la metodología nº1 de forma ligeramente distinta para evaluar propiedades como Process.Id, Process.TotalProcessorTime o Process.StartTime y Process.ExitTime.

EDITO: ups, perdón, basé esta solución en el lenguaje de programación VB.NET, no me di cuenta de que estabamos en el subforo de VB6 xD, de todas formas la idea se puede aplicar igualmente (haciendo uso de las funciones nativas GetProcessId y/o GetProcessTimes si fuese necesario como último recurso).

3.
Mediante la función nativa WriteProcessMemory, según las palabras del compañero @MCKSys Argentina, y previo análisis del executable, al parecer podrías modificar cierta información representativa del proceso creado, como modificar los argumentos command-line... aunque no se haya iniciado con ningún argumento, sería solo añadir (o borrar) algún dato para poder identificar que el proceso lo iniciaste tú cuando te dispongas a leer la información del proceso al detectar el proceso creado.

4.
Puedes modificar el tamaño del archivo L2.exe, me refiero, añadirle una serie de bytes (nulos, o específicos) al final del archivo para poder identificar tu proceso. Esto sería intrusivo, y deberías controlar de forma eficiente la terminación del proceso L2.exe para responsabilizarte de restaurar los bytes originales del archivo L2.exe. Y suponiendo que el juego tenga alguna protección anti-cheat quizás podría dar algún tipo de problema al detectar un tamaño diferente en el executable principal... sería cuestión de probarlo para salir de dudas.

Saludos.