Wypisanie nazwy funkcji

0

Witam!

Mam dużyyy problem :)
otóż chcę wykonać program który wypisuje nazwę/y wszystkich bądź jednej funkcji prócz main.
Np.

W tym wypadku program miałbym wypisać na ekranie nazwę funkcji char tzn funkcja1();

#include <stdio.h>
#include <stdlib.h>

char funkcja1();

int main()
{
// tu cos trzeba
return 0;
}

char funkcja1()
{
printf("mmm");
}

a w tym miałby wypisać nazwy wszystkich funkcji jakie są tzn:
f2, f3, f4;

#include <stdio.h>
#include <stdlib.h>

char f1();
int f2();
void f3();

int main()
{
// tu cos trzeba
return 0;
}

char f1()
{
printf("mmm");
}

int f2()
{
int k = 0;
printf("%d", k);
}

void f3()
{
int k =0;
printf("%d", k);
}

i np. wynikiem działania drugiego programu miało by być cos takiego:
f2(), f3(), f4();

jak takie cos wykonać ??

0

Gdzie jest problem ? ( może w dziale Newbie :-/ )

#include <stdio.h>
#include <stdlib.h>

char f1();
int f2();
void f3();

int main()
{
  f1();
  f2();
  f3();
  getchar();
return 0;
}

char f1()
{
printf("f1(),");

}

int f2()
{
printf("f2(),");

}

void f3()
{
printf("f3()");

}
0

Wydaje mi się, że kakofonia nie chce otrzymywać listy funkcji, które się uruchamiają, w dodatku zrealizowanej tak nieelastycznie. Raczej chce znać listę funkcji, które zostały w danym programie zdefiniowane. A tu raczej nie będzie łatwo.

kakofonia, jakiego kompilatora używasz?

0

Oto przykład jak to zrobić, tylko zmień sobie RELATIVE_PATH na swój plik *.obj.
Program wypisuje nazwy wszystkich exportowanych symboli (funkcje, metody, stringi...)

reference: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
Program uruchomiony z IDE z (currentdir == projectdir) działa poprawnie

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define RELATIVE_PATH  "release\\coffreader.obj"

// nie 'zmanglowana' funkcja cdecl
extern "C" void _funkcja_extern_c_cdecl() {};

// nie 'zmanglowana' funkcja stdcall
extern "C" void __stdcall _funkcja_extern_c_stdcall_() {};

// 'zmanglowana' funkcja cdecl
void _funkcja_zmanglowana_() {};

// jakaś klasa...
class CSomeClass
{
public:
	void SomeMethod(int SomeArg); // dodaj virtual :)
};


void CSomeClass::SomeMethod(int SomeArg) {}



int main()
{
	DWORD d;
	IMAGE_FILE_HEADER hdr;
	HANDLE hFile = CreateFile(RELATIVE_PATH, GENERIC_READ,0,0,OPEN_EXISTING,0,0);
	// wczytaj nagłówek COFF
	ReadFile(hFile, &hdr, sizeof(hdr), &d,0);

	// wczytaj wszystkie sekcje
	DWORD sectionslen = hdr.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
	IMAGE_SECTION_HEADER *sections = (IMAGE_SECTION_HEADER*)malloc(sectionslen);
	ReadFile(hFile, sections, sectionslen, &d, 0);

	// wczytaj wszystkie nazwy symboli
	SetFilePointer(hFile, hdr.PointerToSymbolTable + (hdr.NumberOfSymbols * sizeof(IMAGE_SYMBOL)), 0, FILE_BEGIN);
	DWORD dwSize;
	// stringtable zaczyna się od i zawiera DWORD size
	ReadFile(hFile, &dwSize, 4, &d,0);
	char* names = (char*)malloc(dwSize+4);
	ReadFile(hFile, names+4, dwSize, &d, 0);

	// wypisz wszystkie globalne sybmole
	// czyli te exportowane dla innych modułów
	SetFilePointer(hFile, hdr.PointerToSymbolTable, 0, FILE_BEGIN);

	for (DWORD s=0; s<hdr.NumberOfSymbols; s++)
	{
		IMAGE_SYMBOL symbol;
		ReadFile(hFile, &symbol, sizeof(IMAGE_SYMBOL), &d,0);
		// if (!SectionNumber) - symbol jest importowany
		if ((symbol.SectionNumber > 0) && (symbol.StorageClass == IMAGE_SYM_CLASS_EXTERNAL))
		{
			if (symbol.N.Name.Short)
			{
				// nazwa symbolu ma max 8 znaków, znajduje się w strukturze
				char sname[12]; sname[8] = 0;
				strncpy(sname, (char*)&symbol.N.ShortName, 8);
				printf("short: %s\n", sname);
			}
			else
			{
				// nazwa symbolu przekracza 8 znaków, znajduje się w stringtable
				printf("%s\n", &names[(int)symbol.N.Name.Long]);
			}
		}
	}
	free(sections);
	free(names);
	CloseHandle(hFile);
	return _getch();
}
0

Witam!

No własnie nie chodziło mi o to by wywołac funkcjie ... bo to to jest banalne ....
Chodziło mi o wypisanie listy funkcji jakie znajdują sie w programie oprocz funkcji main.
Niestety oferowany przez kolege rozwiązanie jest dla mnie nie dobre gdyż używam gcc 4.01 czy jakoś tak (pod linuksem pracuje).

Będę wdzieczny za pomoc :)
Pozdrawiam

0

Podejrzewałem że chodzi o podanie nazw funkcji z gotowego pliku wykonywalnego.
Niestety , na pewno nazwy funkcji nie istnieją po kompilacji w pliku wykonywalnym w srodowisku
Windows ( dla tego sądziłem że chodzi o jakieś proste zadanie - a teraz działa taka fun() i takie tam ..) .
W Linuksie - nie wiem , najprościej napisać jakis program , i "zajrzeć" do środka (Hex) czy jest w ogóle
czego szukać .

0

Oczywiście, że jest czego szukać, zarówno pod Windows, jak i pod Linuksem, jak i wszędzie indziej. Dobra, znam już środowisko, to mogę ogólnie napisać co i jak, ale źródła nie podam, bo:

  1. nie mam DJGPP ani Linuksa, nie mam na czym testować
  2. nie chce mi się ;]

Nazwy funkcji będą, pod warunkiem, że się pracuje z debuggerem i każe mu się dodać informacje o symbolach etc do pliku podczas kompilacji. Funkcja podana przez sapero jest świetna i bardzo się przydała, bo wskazała ci dobrą drogę, moim zdaniem. Napisał on wyciąganie funkcji z pliku COFF - GCC też COFFy generuje, w miarę podobne, więc przeanalizowanie źródła da ci już pojęcie, jak się samemu do tego zabrać.

  1. musisz dodać do programu informacje dla debuggera: kompilujesz z opcją -g, ale bez -O. Dzięki temu w kodzie będą nry lini, nazwy funkcji, nazwy zmiennych etc

  2. musisz teraz te informacje wyciągnąć - debugger może, to ty też. Ogólne wyjaśnienie zasad przechowywania danych w plikach wykonywalnych masz tutaj
    http://rainbow.mimuw.edu.pl/SO/Projekt05-06/temat3-g2/index.pdf

  3. konkrety musisz wycisnąć z opisu formatu COFF generowanego przez DJGPP - nie ma że boli. Skocz na:
    http://www.delorie.com/djgpp/doc/coff/
    i przyglądnij się sekcjom: Symbol Table i String Table. Jakkolwiek, żeby je zrozumieć, to będziesz musiał raczej przeczytać również wcześniejsze sekcje ;) Nie panikuj, dokument nie jest długi, możesz go sobie w jeden dzień przeczytać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1