niedziela, 14 czerwca 2009

Hakowanie w Accessie

Czasem mamy twardy orzech do zgryzienia z bazą napisaną przez nas lub przez kogoś obcego a występująca jedynie w postaci pliku mde - czyli wersji skompilowanej. Dla niewtajemniczonych plik taki to w pełni działająca aplikacja w której nie da się modyfikować formularzy, raportów i kodu VBA. Modyfikacja kwerend i makr jest dozwolona.

Naszym zadaniem jest poznanie Connection Stringa tak aby wydobyć z niego hasło, gdyż mamy niecny plan napisania lepszej aplikacji i potrzebujemy zalogować się na ten zewnetrzny serwer SQL.
Jeżeli w aplikacji znajduje się tabela podlinkowana lub kwerenda przekazująca to problem jest banalny. W przypadku zaś gdy nie ma takich obiektów jest trochę trudniej, ale nie beznadzijnie ;)
Do tego zadania wykorzystamye pewną cechę środowiska Access, które nie są wykorzystywana w codziennej pracy, a mianowicie możliwość dodania referencji w projekcie VBA do pliku mdb/mde dokładnie tak samo jak do biblioteki dll.



Na obrazku widzimy dodany do referencji projektu plik z tajnymi danymi. Na pasku bocznym zaś projekt będzie wyglądał następująco:



Widzimy listę obiektów do których możemy przeszukać pod kątem występowania obiektów do wykorzystania. Przeszukiwanie najłatwiej zrealizować za pomocą Object Browser-a

Ikonka Object Browser-a

Wybieramy tam z listy rozwijanej plik który przeszukujemy:



Pewną niedogodnością jest to że musimy się domyśleć jak działa sprawdzana aplikacja, gdyż obiekt do którego się odwołujemy sam z siebie może nie mieć oczekiwanych danych. Przy odrobinie szczęścia można dojść do tego na drodze dedukcji :)

Teraz najważniejsze: W jaki sposób dobrać się do takich danych?
Trzeba poprostu odwołać się do obiektu dokładnie tak samo jak by był normalnym obiektem, funkcją lub procedurą. Przykładowy kod poniżej
Sub test_conn()
Dim oConn As ADODB.Connection

mod_conn.Connec

Set oConn = mod_conn.fGetConn

Debug.Print oConn.ConnectionString
Debug.Print CurrentProject.Connection.ConnectionString

mod_conn.CloceConn

End Sub


przykładowy kod w module mod_conn wyglądał by np. tak:
Option Compare Database
Option Explicit

Private oConn As ADODB.Connection

Sub Connec()

Set oConn = New ADODB.Connection
oConn.ConnectionString = "Provider=sqloledb;Server=PRZEMEK-PC\SQLEXPRESS;Database=Aplikacja;Trusted_Connection=yes;"
oConn.Open

End Sub

Function fGetConn() As ADODB.Connection
Set fGetConn = oConn
End Function

Sub CloceConn()
oConn.Close
Set oConn = Nothing
End Sub

Widzimy tu że konieczne jest zainicjowanie połączenia za pomocą procedury Connec, informacje zaś o obiekcie Connection uzyskamy z funkcji fGetConn.

Jak się bronić?

Metoda jest bardzo prosta :) pisać kod w klasach, gdyż nie można utworzyć nowej instancji klasy znajdującej się w pliku z referencji.

pod tym linkiem można pobrać pliki do analizy w domowym zaciszu: projekt apollo

środa, 3 czerwca 2009

Krótka bajka o skracaniu (kodu)

Pokażę dziś w jaki sposób można sobie maksymalnie ułatwić życie wykorzystując pewne cechy programowania w VBA. Mi samemu z początku wydawało się to trochę abstrakcją, lecz po kilku(set) wykorzystanych razach stało się wręcz niezbędne. Ale do rzeczy :)

Język VBA udostępnia nam możliwość skracania odwołań do obiektów poprzez zastosowanie konstrukcji With....End With
With Obiekt
kod
End With
Gdzie:
Obiekt jak sama nazwa wskazuje jest Obiektem który będziemy wykorzystywać wielokrotnie
kod to czynności które wykonamy wykorzystując wcześniej zadeklarowane odwołanie do obiektu czyli korzystamy z jego metod i właściwości poprzedzając je znakiem kropki np.
.top = 10
Ciekawostką jest to że obiektem może być dowolne coś co zwraca nam w wyniku operacji zmienną obiektową np.
Function getFromTable(id As Integer) As Variant
With CurrentProject.Connection.Execute("select opishtml from tabela where id =" & id)
If .EOF Or .BOF Then getFromTable = Empty: Exit Function
getFromTable = Nz(.Fields.Item(0).Value, Empty)
End With
End Function
Wykorzystuję tu fakt że wynikiem wykonania metody .Execute jest obiekt ADODB.Recordset. Fakt jest to mocno niejawne ale działa :)

Wyjaśnienia mogą jeszcze wymagać elementy .EOF or .BOF - jest to sprawdzenie czy rekordset przypadkiem nie jest pusty. Gdyby był to kolejna linia wygenerował by błąd
getFromTable = Nz(.Fields.Item(0).Value, Empty)
Ta linia natomiast podstawia pod zmienną wartość elementu o indeksie 0 z kolekcji .Fields. Elementy tej kolekcji budują pojedynczy wiersz Recordset-a. Sprawdzam przy okazji czy wartość przypadkiem nie jest Null i jak jest to podstawiam Empty
Funkcja Nz jest z defaultu dostępna tylko w Accessie, ale bardzo łatwo ją skonstruować samodzielnie z wykorzystaniem funkcji logicznej IsNull(zmienna) oraz IF albo jeszcze szybciej IIF. Dla niewtajemniczonych funkcja ta sprawdza czy podany parametr jest wartością Null i jeżeli tak to podstawia pod wartość końcową drugi parametr. W przeciwnym wypadku jest zwracana wartość pierwotna.

Poniżej trzy wersje funkcji Nz. Mogą być przydatne np. w Excelu
Function Nz(vIn As Variant, vIsNull As Variant) As Variant
If IsNull(vIn) Then
Nz = vIsNull
Else
Nz = vIn
End If
End Function

Function Nz(vIn As Variant, vIsNull As Variant) As Variant
Nz = vIn
If IsNull(vIn) Then Nz = vIsNull
End Function

Function Nz(vIn As Variant, vIsNull As Variant) As Variant
Nz = IIf(IsNull(vIn), vIsNull, vIn)
End Function


Morał
Wykorzystanie With ma wiele zalet jedną z nich jest możliwoć skrócenia kodu i jego wizualna optymalizacja. Kolejną niewątpliwą zaletą jest przyspieszenie kodu.

wtorek, 2 czerwca 2009

Akcelerator konwersji kodu z C# do VB.NET

Przeglądając internet natknąłem się na przepis do robienia akceleratora, czyli małego aktywnego gadżetu ułatwiającego surfowanie po internecie :)
Technologię tą wspiera Internet Explorer. Samo wykonanie nie jest technicznie trudne gdyż ogranicza się do spreparowania pliku .xml oraz dodaniu guzika lub przygotowaniu linka.
Poświeciłem godzinę czasu i owocem tego jest akcelerator przekazujący kod w C# do VB.NET. Oryginalny translator jest dostępny na stronie:



// Hello1.cs
public class Hello1
{
public static void Main()
{
System.Console.WriteLine("Hello, World!");
}
}


kod akceleratora, umieściłem go w sieci pod adresem http://scalacz.googlecode.com/files/install.xml:

http://www.developerfusion.com/tools/convert/csharp-to-vb/

Convert C# to VB.NET
http://www.developerfusion.com/favicon.ico











wywołanie za pomocą guzika:



oraz wywołanie za pomocą linku

C# to VB.NET Accelerator


Korzystanie:


Miłej zabawy :)